前置
性能分析工具
pnpm add progress-bar-webpack-plugin -D
配置
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
// ...
plugins: [
// 代码产物分析
new BundleAnalyzerPlugin(),
],
}

webpack 构建流程
- 初始化
- 根据配置文件、Shell 参数以及默认配置结合得出最终的配置参数
- 创建编译器对象 compiler
- 初始化编译环境
- 编译开始,执行 compiler 的 run 方法,创建 compilation 对象
- 确定入口
- 构建
- 编译模块
- 完成编译模块,得到依赖关系图
- 封装
-
根据依赖关系进行打包
-
对包进行优化,tree-shaking、压缩 等
-
写入系统
缓存
在 webpack 5 中提供了缓存的功能,通过 cache.type = 'filesystem' 即可开启持久化缓存。
开启持久化缓存后,webpack 会在首次构建时,将构建出的产物模块序列化然后保存到硬盘,后面再执行构建时,就可以跳过很多编译过程,直接复用缓存。
图像优化
压缩
关于图片压缩这里使用的是 image-webpack-loader。
pnpm add -D image-webpack-loader
配置
rules: [
{
test: /\.(gif|png|jpe?g|svg)$/i,
type: "asset/resource",
use: [{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true,
quality: 65,
}
}
}]
},
]
options 有多种属性
- mozjpeg:压缩 JPG(JPEG) 图片
- optipng、pngquant:压缩 PNG 图片
- svgo:压缩 SVG 图片
- gifsicle:压缩 Gif 图
- webp:将 JPG/PNG 图压缩并转化为 WebP 图片格式
打包体积优化
使用 cdn 分包
将项目中体积较大的包通过 cdn 的方式引入,减少打包产物体积大小。
pnpm add html-webpack-externals-plugin -D
配置
plugins: [
// ...
new HtmlWebpackExternalsPlugin({
externals: [
{
module: 'react',
entry: 'https://unpkg.com/react@18.2.0/umd/react.production.min.js',
global: 'React',
},
]
})
],
这里以 react 为例,使用 cdn 的方式引入,不再打包进入产物
打包速度优化
多进程打包
pnpm add -D thread-loader
配置
rules: [
{
test: /\.js$/,
use: [
{
loader: "thread-loader",
options: {
workers: 2,
workerParallelJobs: 50,
},
},
// ...
]
}
]
-
workers 进程总数
-
workerParallelJobs 单个进程中并发执行的任务数
-
poolTimeout 超时时间,子进程空闲超时会关闭
-
poolRespawn 是否允许子进程关闭后重新创建新的子进程
-
workerNodeArgs 设置启动子进程时,额外的参数
按需编译
webpack 提供一个实验特性 lazyCompilation用来实现异步引用模块的按需编译,极大提高了冷启动速度。
module.exports = {
// ...
experiments: {
lazyCompilation: true,
},
};
但是该功能还处在实验阶段,最好只在开发环境使用。
约束 loader 执行的范围
通过 module.rules.exclude / module.rules.include 可以进一步缩小 loader 的执行范围。
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
// ...
},
],
使用 noParse
使用 module.noParse 跳过不需要二次编译的资源文件。
module.exports = {
//...
module: {
noParse: /lodash|react/,
},
};
关闭 ts 的类型检查
使用 fork-ts-checker-webpack-plugin 插件来进行 ts 的类型检查,该插件会将 ts 的类型检查和编译过程放在单独的进程中运行,然后我们关闭 ts-loader 的类型检查,提升编译速度。
pnpm add -D fork-ts-checker-webpack-plugin
配置
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
module.exports = {
module: {
rules: [{
test: /\.ts$/,
use: [
{
loader: 'ts-loader',
options: {
// 仅编译
transpileOnly: true
}
}
],
}, ],
},
plugins:[
new ForkTsCheckerWebpackPlugin()
]
};
代码压缩
代码压缩就是抛弃代码的可读性、格式化等等一切,把我们的代码做到最精简。
js 压缩
webpack 5 默认使用 terser 进行 js 压缩,通过 optimization.minimize 属性开启。
css 压缩
使用 css-minimizer-webpack-plugin 插件来完成对 css 的压缩
pnpm add -D css-minimizer-webpack-plugin
配置
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
module.exports = merge(common, {
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin(),
],
},
});
该插件还可以通过 minify 属性来指定使用什么进行压缩,可选值:
CssMinimizerPlugin.cssnanoMinify使用 cssnano 默认值,不需要额外安装依赖CssMinimizerPlugin.cssoMinify使用 cssoCssMinimizerPlugin.cleanCssMinify使用 clean-cssCssMinimizerPlugin.esbuildMinify使用 ESBuildCssMinimizerPlugin.parcelCssMinify使用 parcel-css
需要注意的是,该插件必须配合之前提到的 mini-css-extract-plugin 插件一起使用,mini-css-extract-plugin 插件将 css 代码抽离到一个文件,css-minimizer-webpack-plugin 再对代码进行压缩。
html 压缩
pnpm add -D html-minifier-terser
配置
module.exports = merge(common, {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
parallel: 2 // number | boolean
}),
new CssMinimizerPlugin({
minify: CssMinimizerPlugin.cssnanoMinify,
}),
],
},
});
gzip
pnpm add -D compression-webpack-plugin
配置
const CompressionPlugin = require('compression-webpack-plugin');
module.exports = {
plugins: [
new CompressionPlugin({
algorithm: 'gzip',
test: /\.(js|css)$/,
}),
],
};