webpack5的优化

104 阅读3分钟

1.png

webpack5基本使用 篇的基础上进行:

一. 优化效率的工具:

  • progress-bar-webpack-plugin:查看编译进度;
  • speed-measure-webpack-plugin:查看编译速度;
  • webpack-bundle-analyzer:打包体积分析。
  1. 编译进度条:

安装:npm i -D progress-bar-webpack-plugin

在webpack.config.js文件中配置:

// 引入进度条插件
const chalk = require("chalk");//引入node 颜色的插件
const ProgressBarPlugin = require("progress-bar-webpack-plugin");
module.exports = {
  plugins: [
    // 进度条
    new ProgressBarPlugin({
      format: `  :msg [:bar] ${chalk.green.bold(":percent")} (:elapsed s)`,
    }),
  ],
};

效果图:

1.png

  1. 编译速度:

安装:npm i -D speed-measure-webpack-plugin

在webpack.config.js文件中配置:

// 引入编译速度插件
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
module.exports = {
  plugins: [
    // 编译速度
        new SpeedMeasurePlugin({
            
        }),
  ],
};

效果图:

1.png

  1. 打包体积: 使用时参考 插件配置

安装: npm i -D webpack-bundle-analyzer

在webpack.config.js文件中配置:

// 引入打包体积插件
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
module.exports = {
  plugins: [
    // 打包体积
        new BundleAnalyzerPlugin({
            
        }),
  ],
};

效果图:

1.png

二. 优化手段

1. exclude/include

通过 exclude、include 配置转译尽可能少的文件。exclude 指定要排除的文件,include 指定要包含的文件;由于exclude 的优先级高于 include,在 include 和 exclude 中使用绝对路径数组,所以尽量使用 include。

在webpack.config.js配置:

module.exports = {
    //...
    module:{
        rules:[
            // 打包css
            {
                test: /\.css$/i, //正则匹配需要打包的文件名
                use:[MiniCssExtractPlugin.loader,'css-loader','postcss-loader',],//打包需要的loader,注意顺序
                // exclude:/node-moules/,//不需要查找解析的文件
                include: [path.resolve(__dirname, 'src')],//需要查找解析的文件
            },
            
        ]
    }
}

2. Cache

通过配置 webpack 持久化缓存 cache: filesystem,将构建过程的 webpack 模板和chunk进行缓存,大幅提升二次构建速度、打包速度,当构建突然中断,二次进行构建时,可以直接从缓存中拉取,可提速 90% 左右。原理是:判断前后哈希值或时间戳是否发生变化来判断是否直接使用之前缓存。

在webpack.config.js中配置:

module.exports = {cache: {type: "filesystem", // 使用webpack 持久化文件缓存},}; 

注意: 前后打包输出的文件名是一样的,都叫 index.js,一旦将来发布新版本,因为文件名没有变化导致浏览器会直接读取缓存,不会加载新资源,项目也就没法更新。所以从文件名入手,确保更新前后文件名不一样就可以。

3. 尽量减少 loader 配置数量

比如对图片打包尽量使用 webpack5基本使用 文章中的第一种方法。

4. 多进程(thread-loader)

通过多进程来实现,在非常耗时的 loader 前引入 thread-loader。比如将 sass-loader 放在一个独立的 worker 池中运行,就不会阻碍其他 loader 的构建,可以大大加快构建速度。

安装: npm i -D thread-loader

配置:

 module:{//loaders的配置都在module对象的rules中配置
       rules:[
            // 打包css
            {
                test: /\.css$/i, //正则匹配需要打包的文件名
                use:[MiniCssExtractPlugin.loader,'css-loader','postcss-loader',{
                    loader:'thread-loader',
                    options: {
                        workerParallelJobs: 2,
                      },
                }],//打包需要的loader,注意顺序
                // exclude:/node-moules/,//不需要查找解析的文件
                include: [path.resolve(__dirname, 'src')],//需要查找解析的文件
            },
           ]
       }

注意:

  • 一定要是在非常耗时的loader才添加thread-loader(极有可能会因为多开进程导致耗时),测试一遍;
  • webpack 官网 提到 node-sass 中有个来自 Node.js 线程池的阻塞线程的 bug。 当使用 thread-loader 时,需要设置 workerParallelJobs: 2

5. 压缩代码体积

通过 webpack 插件,将 JS、CSS 等文件进行压缩

5-1 压缩js代码:

使用 TerserWebpackPlugin 来压缩 JavaScript

安装: npm install terser-webpack-plugin --save-dev

在webpack.config.js中配置:

// 引入压缩js插件
const TerserPlugin = require("terser-webpack-plugin");
module.exports = {
    optimization: {
        minimizer: [
            new TerserPlugin({
                test: /\.js(\?.*)?$/i,
                parallel: true,//默认为true,若配置的 parallel 数量,使用多进程并发运行压缩以提高构建速度。
                extractComments: true,
                terserOptions: {
                    output: {
                        // 是否输出可读性较强的代码,即会保留空格和制表符,默认为输出,为了达到更好的压缩效果,可以设置为false
                        beautify: false,
                        // 是否保留代码中的注释,默认为保留,为了达到更好的压缩效果,可以设置为false
                        comments: false
                    },
                    compress: {
                        // 是否在UglifyJS删除没有用到的代码时输出警告信息,默认为输出,可以设置为false关闭这些作用不大的警告
                        warnings: false,
                        // 是否删除代码中所有的console语句,默认为不删除,开启后,会删除所有的console语句
                        drop_console: true,
                        drop_debugger: true,
                        // 是否内嵌虽然已经定义了,但是只用到一次的变量,比如将 var x = 1; y = x, 转换成 y = 5, 默认为不转换,为了达到更好的压缩效果,可以设置为false
                        collapse_vars: true,
                        // 是否提取出现了多次但是没有定义成变量去引用的静态值,比如将 x = 'xxx'; y = 'xxx'  转换成var a = 'xxxx'; x = a; y = a; 默认为不转换,为了达到更好的压缩效果,可以设置为false
                        reduce_vars: true,
                        pure_funcs: ['console.log'] // 移除console
                    }
                }
            }),
        ],
      },
}

效果图:

1.png

5-2 压缩css代码

安装 :npm install -D css-minimizer-webpack-plugin css-minimizer-webpack-plugin

配置:

// 引入压缩css插件
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
module.exports = {
    optimization: {
        minimizer: [
            new CssMinimizerPlugin({
                parallel: 4,
            }),
        ]
      }
  }

注意:与css代码分离插件一起使用

5-3. 抽离重复代码1抽离重复代码2 , 第12条

5-4. tree shaking(摇树优化): Tree Shaking 只支持 ESM 的引入方式,不支持 Common JS 的引入方式,但是项目中的Babel 编译器会将 ES5 模块语法转换为 CommonJS 模块,所以不推荐使用该优化方法。官网

5-5. externals:对第三方包进行公共包CDN引用,降低包大小, 参考:

6. hard-source-webpack-plugin 插件不适合用于 webpack5 , 报错如下,用前面的 cache 缓存就行。

1.png

优化的方法还有很多

参看文章: