webpack从入门到原理(高级四)——多进程打包(提高打包构建速度)

222 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第10天,点击查看活动详情

前言

通过前面对webpack的Include/Exclude和Cache配置,已经能够大大提升webpack的打包构建速度,但是随着代码体量越来越大,项目越来越庞大时,打包速度越来越慢,甚至于需要一个下午才能打包出来代码。这时我们就需要继续提升打包速度,也就是要提升 js 的打包速度,因为其他文件都比较少。而对 js 文件处理主要就是 eslint 、babel、Terser 三个工具,所以下面我们就要提升它们的运行速度。

Thead

想要提升eslint 、babel、Terser的运行速度我们可以开启多进程同时处理 js 文件,也就是开启电脑的多个进程同时干一件事,这样速度就比之前的单进程打包更快了。

注意:请仅在特别耗时的操作中使用,因为每个进程启动就有大约为 600ms 左右开销

使用

我们能够启动进程的数量就是我们 CPU 的核数,每个电脑的 cpu 核数是不一样的,所以首先需要获取 cpu 核数,可以直接使用下面 node.js 核心模块进行获取。

// webpack.prod.js
// nodejs核心模块,直接使用
const os = require("os");
// cpu核数
const threads = os.cpus().length;

需要使用多线程的话还需要安装thread-loader来做这些事情:

npm i thread-loader -D

babel-loader开启多进程方式

因为要处理loader,就不可以直接写loader了,需要将loader写到use里面,在上面写thread-loader的配置。像下面这样配置babel-loader就开启了多进程,workers为开启的进程数。

// webpack.prod.js
const TerserPlugin = require("terser-webpack-plugin");
......
  {
    test: /\.js$/,
    // exclude: /(node_modules)/,
    include: path.resolve(__dirname, "../src"), // 也可以用包含
    use: [
      {
        loader: "thread-loader", // 开启多进程
        options: {
          workers: threads, // 开启的进程数量(上面以定义)
        },
      },
      {
        loader: 'babel-loader',
        options: {
          cacheDirectory: true, // 开启babel编译缓存
          cacheCompression: false, // 缓存文件不要压缩
        },
      }
    ]
  }

eslint开启多进程方式

eslint开启多进程只需要增加threads进程数就可以开启多进程和设置进程数。

// webpack.prod.js
  plugins: [
    new ESLintPlugin({
      context: path.resolve(__dirname, '../src'), // 需要检查的文件路径
      exclude: 'node_modules',
      cache: true, // 开启缓存
      cacheLocation: path.resolve(__dirname, "../node_modules/.cache/.eslintcache"), // 缓存目录
      threads, // 开启多进程
    }),
]

压缩js方式

压缩js的插件webpack已经内置,直接引入即可使用。

// webpack.prod.js
const TerserPlugin = require("terser-webpack-plugin");
......

写法一

// webpack.prod.js
const TerserPlugin = require("terser-webpack-plugin");
......
plugins:[
    new TerserPlugin({
      parallel: threads // 开启多进程
    })
]

写法二

在webpack5官方写法中压缩文件是放在minimizer中,当然两种方法都可以!

// webpack.prod.js
const TerserPlugin = require("terser-webpack-plugin");
......
module.exports = {
......
    optimization: {
        minimizer: [
          // css压缩也可以写到optimization.minimizer里面,效果一样的
          new CssMinimizerPlugin(),
          // 当生产模式会默认开启TerserPlugin,但是我们需要进行其他配置,就要重新写了
          new TerserPlugin({
            parallel: threads // 开启多进程
          })
        ],
    }
......
}

以上就完成了对 eslint 、babel、Terser 多进程的配置,开发模式是和生产模式配置是一样的。

小结

通过对 eslint 、babel、Terser 多进程的配置可以提升代码打包速度,需要注意的是只有当代码达到一定体量时打包速度才会有明显提升,因为进程启动需要时间,所以代码量小时打包速度反而会慢。