Skip to content

提高构建速度

多线程解析资源

使用 thread-loader 解析资源

原理:每次 webpack 解析一个模块,thread-loader 会将它及它的依赖分配给 worker 线程中

shell
npm install --save-dev thread-loader
js
module.exports = {
  module: {
    rules: [{
      test: /\.js$/,
      include: path.resolve('src'),
      use: [
        'thread-loader',
        // your expensive loader (e.g babel-loader)
      ],
    }, ],
  },
};

并行压缩

terser-webpack-plugin 开启 parallel 参数

js
const TerserPlugin = require('terser-webpack-plugin')

module.exports = {
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        parallel: true,
      }),
    ],
  },
};

让 webpack 少做点事

减少 resolve 的解析

通过精简 resolve 配置,让 webpack 在查询模块路径时尽可能快速地定位到需要的模块,不做额外的查询工作

js
resolve: {
  modules: [
    path.resolve(__dirname, 'node_modules'), // 使用绝对路径指定 node_modules,不做过多查询
  ],
  // 删除不必要的后缀自动补全,少了文件后缀的自动匹配,即减少了文件路径查询的工作
  // 其他文件可以在编码时指定后缀,如 import('./index.scss')
  extensions: [".js"],
  // 避免新增默认文件,编码时使用详细的文件路径,代码会更容易解读,也有益于提高构建速度
  mainFiles: ['index'],
}

loader 应用的文件范围缩小

在使用 loader 的时候,尽可能把 loader 应用的文件范围缩小,只在最少数必须的代码模块中去使用必要的 loader

js
rules: [{
  test: /\.jsx?/,
  include: [
    path.resolve(__dirname, 'src'),
    // 限定只在 src 目录下的 js/jsx 文件需要经 babel-loader 处理
    // 通常我们需要 loader 处理的文件都是存放在 src 目录
  ],
  use: 'babel-loader',
}, ],

DLL

react react-dom redux 等基础包和业务基础包打成一个文件

  1. 需要新建个构建配置文件,比如是 webpack.dll.config.js
js
module.exports = {
  context: process.cwd(),
  entry: {
    library: [
      'react',
      'react-dom',
      'redux',
      'react-redux'
    ],
    // 如果有多个,直接在增加一个
  },
  output: {
    // 这里打包后的文字是 library.dll.js
    filename: '[name].dll.js',
    path: path.resolve(__dirname, 'build/libarary'),
    // 暴露的库的名字
    library: '[name]'
  },
  plugins: [
    // 指定包存放的位置
    new webpack.DllPlugin({
      name: '[name]',
      // 描述动态链接库 mainfest 文件输出时的文件名称
      // path: 'manifest.json'
      path: path.resolve(__dirname, 'build/libarary/[name].json')
    })
  ]
}
  1. pageage.json scripts 中增加命令
json
"scripts": {
  "dll": "webpack --config webpack.dll.js"
}
  1. 执行 npm run dll 分包
  2. webpack.config.js 引入
js
module.exports = {
  plugins: [
    new webpack.DllReferencePlugin({
      // 刚打包后的json文件地址
      // manifest: require('xxx.json'),
      manifest: require('./build/library/libary.json'),
      // 指定需要用到的 manifest 文件,
      // webpack 会根据这个 manifest 文件的信息,分析出哪些模块无需打包,直接从另外的文件暴露出来的内容中获取
    })
    // 如果引入多个,使用多次此插件
  ]
}
  1. 每次公共部分代码的变化,都需要重新执行分包指令

利用缓存提升构建速度

通过开启缓存来提升二次构建速度,开启缓存后 node_modules 下会有一个 .cache 目录

babel-loader 开启缓存

js
use: [{
  loader: 'babel-loader',
  options: {
    cacheDirectory: true
  }
}]

terser-webpack-plugin 开启缓存

js
module.exports = {
  optimization: {
    minimizer: [
      new Terserplugin({
        parallel: true,
        cache: true
      })
    ]
  }
}

使用 cache-loader

在一些性能开销较大的 loader之前添加 cache-loader,以将结果缓存到磁盘里,显著提升二次构建速度

js
module.exports = {
  module: {
    rules: [{
      test: /\.ext$/,
      use: ['cache-loader', ...loaders],
      include: path.resolve('src'),
    }, ],
  },
};