likes
comments
collection
share

Webpack提高

作者站长头像
站长
· 阅读数 18

1.配置拆分、合并

在上一章的基本使用部分呢,我们知道了webpack.config.js中,配置有一个mode,是来规定当前的打包是属于开发环境的development,还是生产环境的production

这里呢,我们根目录下创建一个build文件夹,里面放三个文件,分别是基础配置,也就是除了mode之外的所有配置。另外两个是开发环境和生产环境。

webpack.bace.config.js

 //上一篇文章中webpack.config.js中 除去mode外的所有配置

开发环境配置 webpack.dev.config.js

 //先将基础配置引入
 const commonConfig = require('./webpack.base.config');
 ​
 //定义开发配置
 const devConfig = {
     mode:'development'
 }
 ​
 //使用webpack的一个模块,来合并配置
 const { smart:merge } = require('webpack-merge')
 ​
 module.export = merge(commonConfig,devConfig)

生产环境配置 webpack.prod.config.js

 const commonConfig = require('./webpack.base.config');
 const { smart:merge } = require('webpack-merge')
 ​
 //定义生产配置
 const proConfig = {
     mode:'production'
 }
 ​
 module.export = merge(commonConfig,proConfig)

接下来呢,在package.json中给他们分别添加脚本

 "scripts":{
     "build:dev": "webpack --config ./build/webpack.dev.config.js",
     "build": "webpack --config ./build/webpack.prod.config.js",
 }

这样呢根据不同的情况执行 build:dev或是build 就可以了。

2.处理样式

webpack默认呢,其实是不能对css文件进行打包,只能对js文件进行打包。

这边有三个工具:

style-loader:将css代码插入到页面的

css-loader:处理css文件之间的关系(相互引用等)

postcss-loader:处理css代码与浏览器的兼容性

在我们的webpack配置中添加module规则。

 module.export = {
     module:{
         rules:[
             {
                 test: /.css$/,
                 loader:[
                     'style-loader',
                     'css-loader',
                     'postcss-loader',
                     //loader执行顺序是从下往上执行的
                 ]
             }
         ]
     }
 }

postcss-loader内部实际上依赖了一个autoprefixer这样的一个插件的。

我们需要创建一个 postcss.config.js 配置文件

 module.export = {
     plugins:{
         require('autoprefixer')
     }
 }

另外呢,还需要在package.json里面配置一个browerslist,我们的项目所针对浏览器进行设置

 "browerslist":[
     "> 1%",
     "last 2 versions"
 ]

同样呢,如果有.scss样式的话,可以加入sass-loader工具来处理。

3.处理图片

像css一样,webpack一样处理不了图片。所以要配置规则来处理图片文件。

对于图片呢,在开发环境和生产环境下不一样的

开发环境webpack.dev.config.js

 const devConfig = {
     mode: "development",
     module:{
         rules:[
             {
                 test: /.(png|jpg)$/,
                 loader: 'file-loader'  //会在dist中自动创建图片来使用,就可以看到了
             }
         ]
     }
 }

生产环境中,就得考虑图片的大小。一张大图片可以跟上面方式一样打包,如果是小图片我们可以使用base64字符串的方式进行打包。

生产环境webpack.prod.config.js

 const prodConfig = {
     mode: 'production',
     module: {
         rules:[
             test: /.(png|jpg)$/,
             use:{
                 loader: 'url-loader',
                 options:{
                     //文件大小的限制,在这个限制之内的就会以base64字符串的方式显示
                     limit: 30*1024,
                     outputPath: '/img/' //在dist文件夹下就会创建一个img文件夹
                 }
             }
         ]
     }
 }

这样做的好处嘞,就是如果是比较小的图片,转换成base64格式,可以减少http请求。

而比较大的图片,依旧像file-loader一样,单独打包到 img 文件夹里,发送请求,防止页面首次渲染太慢。

4.多入口

之前的webpack配置中我们的入口都是只有一个index.js,那么多入口要这么配置

 module.exports ={
     entry:{
         index:'./src/index.js',
         other:'./src/other.js'
     },
     output:{
       filename: '[name].js'//占位符形式[name],这样上面的index会生成index.js,other生成other.js
       path: path.resolve(__dirname,'../dist')
     },
     plugins:[
         new HtmlWebpackPlugin({
             template: './src/index.html',
             filename: 'index.html',
             chunks: ['index']
         }),
         new HtmlWebpackPlugin({
             template: './src/other.html',
             filename: 'other.html',
             chunks: ['other']
         }),
     ]
 }

5.抽离公共代码

-公共模块

-公共模块的代码不需要重复打包,单独抽离成一个公共模块的文件,然后引用即可。

例如有一个math.js,分别在index.js和other.js中都将他import进去,打包的时候就会在两个文件中都打包一次。

-第三方模块

-第三方模块的代码一般不会轻易更改,不需要在业务代码改变之后再重新打包,单独抽离成一个第三方模块文件,然后引用即可。

在webpack配置文件中,添加一个splitChunks(代码分割):

 module.exports ={
     entry:{
         index:'./src/index.js',
         other:'./src/other.js'
     },
     output:{
       filename: '[name].[contentHash:8].js'
       path: path.resolve(__dirname,'../dist')
     },
     plugins:[
         new HtmlWebpackPlugin({
             template: './src/index.html',
             filename: 'index.html',
             //引入html使用的js文件 , common是公共的js代码 ,vendor是第三方模块的js代码
             chunks: ['index','common','vendor']
         }),
         new HtmlWebpackPlugin({
             template: './src/other.html',
             filename: 'other.html',
             chunks: ['other','common']
         }),
     ],
     //代码分割
     splitChunks:{
         //all     对 同步、异步代码 都做代码分割
         //async   只对 异步代码 做代码分割
         //initial 只对 同步代码 做代码分割
         //同步代码,例如 import lodash from 'lodash'
         //异步代码,例如 import('lodash') import函数的形式
         chunks: 'all',
         cacheGroups:{
             //分别对第三方模块和公共模块进行处理
             //第三方模块
             vendor:{
                 //每个组的名字
                 name:'vendor',
                 //优先级,优先级越高,优先检测处理
                 //第三方模块 可能也会被作为 公共模块 来检测处理,通过高优先级,达到先被当作 第三方模块 来检测处理
                 priority: 1,
                 //检测方法, 例如:检测模块是否来自 node_modules
                 test: /node_modules/,
                 //实际开发中,可以写5*1024,也就是5kb
                 //但这里为了看到 代码分割 效果,先把值设置到最小,就是0
                 minSize: 0,
                 //检测模块被引用了几次
                 //对于 第三方模块 而言,引用 1次 就应该单独打包
                 //对于 公共模块 而言,引用 2次以上 就应该单独打包
                 minChunks: 1,
             },
             //公共模块
             common:{
                 name:'common',
                 priority: 0,
                 minSize: 0,
                 minChunks: 2,
             }
         }
     }
 }