wepack:从入门到实践

时间:2020-7-29 作者:admin

1. webpack是什么

官网对webpack的定义是这样的:webpack是一个现在javascript应用程序的静态模块打包工具。自从出现模块化以后,大家可以将原本一坨代码分离到各个模块中,但是这个引发了一个问题,就是js的每个文件都需要去服务器那,这就导致加载速度变得很慢,于是webpack出现了,他可以将所有的小文件打包成为一个或者多个大文件。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图。其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个bundle。

2. 核心概念

webpack具有四个核心的概念,想要入门webpack,就得先了解这四个核心的概念。

2.1 入口(entry)

Entrywebpack的入口起点指示,他指导者webpack应该从哪个模块开始入手,来作为其构件内部依赖图的开始。可以在配置文件webpack.config.js中配置entry属性来指定一个或者多个入口点。

---webpack.config.js---
const path=require('path')    //单入口写法

//模块化写法是 node 环境独有的,浏览器原生不支持使用
module.exports={
    entry:'./src/index.js'
}


const config = {      //多页面应用程序写法
  entry: {
    pageOne: './src/pageOne/index.js',
    pageTwo: './src/pageTwo/index.js'
  }
};
module.exports=config;

注:在多页面应用汇总,每当页面跳转时,服务器将会获取一个新的HTML文档。

2.2 出口(output)

Output属性告诉webpack在哪里输出它所创建的bundles,也可指bundles的名称,默认位置为./dist。整个应用结构都会被编译到指定的输出文件夹中去,最基本的属性包括filename(文件名)和path(输出路径)。

---webpack.config.js---
module.exports={
    output:{
        path:path.resolve(__dirname,'dist'),
        filename:'[name].[contenthash].js'
    }
}
注:filename设置contenthash,可以在每次文件发生变化时,生成新的js文件。

以上的配置会将输出打包文件放到当前目录下的dist文件夹中。

2.3加载器(loader)

Loaderwebpack能够处理不同的文件。loader可以将所有类型的文件转换为webpack能够处理的有效模块,然后利用webpack的打包能力,对他们进行处理。

在webpack中,loader有两个目标:

  • 识别出应该被对应的loader进行转换的文件。(使用test属性)
  • 转换这些文件,从而使其能够被添加到依赖图中(并最终添加到bundle中)。(使用use属性)
---webpack.config.js---
module.exports={
    module:{
        rules:[{
            test:/\.js$/,
            use:{
                loader:'babel-loader'
            },
            exclude:/node_modules/      //排除node_module里面的js文件。
        },
        {
            test:/\.scss$/,
            use:[
                {loader:'style-loader'},{loader:css-loader},{loader:scss-loader}
            ]
        }
        ]
    }

}

rules属性值是一个数组,每个数组对象表示了不同的匹配规则,test表示匹配不同的文件后缀;use表示匹配到这个文件后调用的loader来处理,如果需要用到多个loader,则用到数组。

loader支持链式传递,loader的处理顺序是从右到左进行调用的。

以处理scss文件为例:scss-loader.scss文件编译为.css文件,css-loader.css文件编译为commonJS模块,style-loaderjs字符串转化为style标签并插入到页面中。

2.4插件(plugin)

plugin的目的在于解决loader无法实现的其他事,从打包优化和压缩,到重新定义环境变量,功能强大到可以用来处理各种各样的任务。

---webpack.config.js---
module.exports={
    plugins:[
        new HtmlWebpackPlugin({
            title:'hello-webpack',
            template:'src/index.html'
        })
    ]
}

插件htmlwebpackplugin的作用是,在每次build完会生动态成对应的html文件,并自动的将loader处理过的文件插入到该html文件中去。

2.5模式(mode)

mode可以通过配置对象的mode属性进行配置,主要值为production或者development。两种模式的区别在于一个是为生产环境编译打包,一个是为了开发环境编译打包。生产环境模式下,webpack会自动对代码进行压缩等优化,省去了配置的麻烦。

wepack:从入门到实践

通过代码分离,将开发环境与生产环境相同的代码抽离出来放到webpack.config.base.js文件中,然后在引入到各自的版本中,可以减少代码的重复。

wepack:从入门到实践

然后在package.json文件中配置,当build文件的时候,使用webpack.config.prod.js配置文件,而start使用默认的配置文件,也就是webpack.config.js文件。

3. 在项目中使用webpack

3.1 清理dist文件

由于使用了contenthash,每次buildjs文件都不同名,但是新的文件并不会覆盖旧的文件,旧的文件一直存在/dist文件夹中,随着编译次数的增加,这个文件夹会变得越来越大,所以我们需要清理/dist文件夹,确保文件夹干净整洁。

3.1.1 在package.json中设置

"script":{
    build:"rimraf dist &&webpack"
}
原理是在build文件前,先清空dist文件夹,然后再生成新的文件。
注:window系统使用rimraf dist,如果使用bash,可以改为 rm -rf dist

3.1.2 使用插件完成

这里需要用到的插件是:clean-webpack-plugin

---webpack.config.js---
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
    plugins: [
        new CleanWebpackPlugin(['dist'])
    ]
};

3.2 搭建开发环境

使用过http-server进行开发时,我们可以打开一个服务器进行实时的预览,虽然http-server也可以用在这里,但是webpack-dev-server提供的预览功能更加强大,而且与webpack结合更紧密。

首先安装依赖:npm i -D webpack webpack-dev-server

---webpack.config.js---
module.exports={
    devServer: {
        port:8080,    //启动服务器端口;
        open: false,     //启用模块热替换
        hot: true,      //启用gzip压缩
        contentBase: [
        path.join(__dirname, "public"), path.join(__dirname, "assets")
  ]
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin({})       //热更新插件     
    ]
}

---package.json---
"script":{
   start:"webpack-dev-server"
}

通过命令行webpack-dev-server来启动服务器,启动后我们发现根目录并没有生成任何文件,因为webpack打包到了内存中,不生成文件的原因在于访问内存中的代码比访问文件中的代码更快。

我们在public/index.html的页面上有时候会引用一些本地的静态文件,直接打开页面的会发现这些静态文件的引用失效了,所以我们devserver中添加了contentBase,指定多个静态资源的目录。

3.3 样式的抽离

我们之前的样式都是通过style-loader插入到页面中去,但是生产环境需要单独抽离样式文件,mini-css-extract-plugin就可以帮我从js中剥离样式,一般是在生产环境中进行样式的抽离。

首先安装依赖:npm i -D mini-css-extract-plugin

---webpack.config.js---
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
    //其他配置
    module: {
        rules: [
            {
                test: /\.less/,
                use: [{
                    loader: isDev ? 'style-loader' : MiniCssExtractPlugin.loader
                },{
                    loader: 'css-loader'
                },{
                    loader: 'less-loader'
                }]
            }
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: "[name].[contenthash].css",
        })
    ]
}

通过使用样式抽离,build会生成.css文件,并在html文件中使用link引入该.css文件。

3.4 使用babel-loader

loader已经在前面讲过如何配置了,但是这里还要拿出来细讲一下,因为这个在项目中非常的重要。babel-loader的作用是将高版本的es语法转换为浏览器能够解析的es5语法。

首先安装依赖:
npm i -D babel-loader @babel/core @babel/preset-env @babel/plugin-transform-runtime

npm i -S @babel/runtime

---webpack.config.js---
module.exports = {
    rules:[{
        test:/\.js/,
        use:{
            loader:{
                loader:'babel-loader'
            }
        },
        exclude:/node_modules/
    }]
}

把babel的配置提取到根目录,并新建一个.babelrc文件:
---.baberlrc---
{
    "presets": [
        "@babel/preset-env"
    ],
    "plugins": [
        "@babel/plugin-transform-runtime"
    ]
}

参考文件

webpack官方中文文档

webpack详细配置全解析

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。