在前面的文章中,我们已经学习了 webpack 的基本使用方法和一些常用的配置项。但是,当我们的项目越来越大,构建时间越来越长时,我们就需要对 webpack 进行一些优化配置,以提高构建速度和性能。
1. 开启多线程构建
在 webpack 构建项目时,一般只会使用一个 CPU 核心,这样会导致构建速度缓慢。我们可以使用 thread-loader 或 HappyPack 等插件来开启多线程构建,以加快构建速度。
1.1 thread-loader
thread-loader 可以将一些耗时的操作(如 babel 转译)放到 worker 池中运行,从而实现多线程构建。
// www.javascriptcn.com code example
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.js$/,
use: [
{
loader: "thread-loader",
options: {
workers: 2, // 开启线程数
},
},
"babel-loader",
],
},
],
},
};1.2 HappyPack
HappyPack 可以将 loader 的执行过程放到子进程中,从而实现多线程构建。
// www.javascriptcn.com code example
// webpack.config.js
const HappyPack = require("happypack");
module.exports = {
module: {
rules: [
{
test: /\.js$/,
use: [
{
loader: "happypack/loader",
options: {
id: "js",
},
},
],
},
],
},
plugins: [
new HappyPack({
id: "js",
loaders: ["babel-loader"],
}),
],
};2. 使用 DllPlugin 和 DllReferencePlugin 预编译资源
当我们的项目中引用了一些体积较大的第三方库(如 React、Vue 等),每次构建时都需要重新打包这些库,导致构建时间变长。我们可以使用 DllPlugin 和 DllReferencePlugin 预编译这些库,以加快构建速度。
2.1 创建 Dll 文件
首先,我们需要创建一个 webpack.dll.js 配置文件,用于打包需要预编译的库。
// www.javascriptcn.com code example
// webpack.dll.js
const path = require("path");
const webpack = require("webpack");
module.exports = {
mode: "production",
entry: {
vendor: ["react", "react-dom"],
},
output: {
path: path.resolve(__dirname, "dll"),
filename: "[name].dll.js",
library: "[name]_dll",
},
plugins: [
new webpack.DllPlugin({
name: "[name]_dll",
path: path.resolve(__dirname, "dll/[name].manifest.json"),
}),
],
};其中,entry 中的 vendor 数组为需要预编译的库名,output 中的 library 为生成的 Dll 文件对外暴露的变量名,plugins 中的 DllPlugin 用于生成一个 manifest 文件,记录了 Dll 文件中每个模块的信息。
然后,我们在命令行中执行以下命令,生成 Dll 文件和 manifest 文件:
webpack --config webpack.dll.js
2.2 引入 Dll 文件
接下来,我们需要在项目中引入生成的 Dll 文件和 manifest 文件。
// www.javascriptcn.com code example
// webpack.config.js
const path = require("path");
const webpack = require("webpack");
module.exports = {
// ...
plugins: [
new webpack.DllReferencePlugin({
manifest: path.resolve(__dirname, "dll/vendor.manifest.json"),
}),
],
};其中,DllReferencePlugin 用于将 Dll 文件中的模块映射到当前的模块中。
3. 使用 tree shaking
tree shaking 是一个用于剔除无用代码的技术,可以大幅减小打包后的文件体积。在 webpack 中,我们可以使用 UglifyJSPlugin 和 OptimizeCSSAssetsPlugin 来实现 tree shaking。
// www.javascriptcn.com code example
// webpack.config.js
const UglifyJSPlugin = require("uglifyjs-webpack-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
module.exports = {
// ...
optimization: {
minimizer: [
new UglifyJSPlugin({
cache: true,
parallel: true,
sourceMap: true,
}),
new OptimizeCSSAssetsPlugin({}),
],
},
};4. 使用缓存和持久化缓存
当我们对代码进行构建时,webpack 会生成一些中间文件,以及一些用于记录构建过程的数据。这些数据可以被缓存起来,以便下次构建时可以直接使用缓存,从而减少构建时间。
4.1 使用缓存
在 webpack 中,我们可以使用 cache-loader 来实现缓存。
// www.javascriptcn.com code example
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.js$/,
use: [
{
loader: "cache-loader",
},
{
loader: "babel-loader",
},
],
},
],
},
};4.2 使用持久化缓存
在 webpack 4 中,我们可以使用 cache 选项来开启持久化缓存。
// webpack.config.js
module.exports = {
// ...
cache: {
type: "filesystem",
cacheDirectory: path.resolve(__dirname, ".webpack_cache"),
},
};其中,type 为缓存类型,cacheDirectory 为缓存目录。
5. 使用 splitChunks 进行代码分割
在项目中,我们可以将一些公共代码(如第三方库、公共组件等)提取出来,打包成一个单独的文件,以便浏览器可以缓存这些文件,从而减少页面加载时间。在 webpack 中,我们可以使用 splitChunks 进行代码分割。
// www.javascriptcn.com code example
// webpack.config.js
module.exports = {
// ...
optimization: {
splitChunks: {
chunks: "all",
minSize: 30000,
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: "~",
name: true,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10,
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
},
},
},
},
};其中,chunks 为需要分割的代码块类型,cacheGroups 用于配置分割的规则。
结语
本文介绍了一些 webpack 的优化配置,包括开启多线程构建、使用 DllPlugin 和 DllReferencePlugin 预编译资源、使用 tree shaking、使用缓存和持久化缓存以及使用 splitChunks 进行代码分割。这些技术可以帮助我们提高构建速度和性能,让我们的项目更加高效。
Source: FunTeaLearn,Please indicate the source for reprints https://funteas.com/post/67da624ea941bf713425de1a