前言
随着项目的不断变大,webpack的打包性能就会影响开发体验,阻碍开发效率提升,webpack打包优化也就变成了至关重要的一环。不得不说的是,webpack打包优化是一个很复杂与繁琐的过程,而且会因不同的项目产生不同的差异,这就导致webpack的打包优化灵活多变。
不过,webpack打包优化总结下来就两个大的方向:
- 压缩打包体积
- 提升打包速度
下面就从这两个方向出发,介绍一下如何对 webpack 项目进行优化。
环境
- "node": "16.5.0"
- "webpack": "^5.64.2",
- "webpack-cli": "^4.9.1",
- "webpack-dev-server": "^4.5.0",
压缩打包体积
1. 打包体积分析工具
webpack-bundle-analyzer:一个 plugin 和 CLI 工具,它将 bundle 内容展示为一个便捷的、交互式、可缩放的树状图形式,便于对打包后的代码进行分析。
npm i webpack-bundle-analyzer -D
包含各个 bundle 的体积分析,效果如下:
2. 代码压缩
- js压缩
webpack5 内置了terser-webpack-plugin插件,无需安装。
new TerserPlugin({
exclude: /node_modules/, // 排除node_modules
parallel: true, // 开启多线程
extractComments: false, // 不生成 license.text
terserOptions: {
toplevel: true, // 最高级别,删除无用代码
}
}),
- css压缩
通过安装 css-minimizer-webpack-plugin,使用 cssnano 优化和压缩 CSS。
npm i css-minimizer-webpack-plugin -D
具体配置如下:
new CssMinimizerPlugin({
parallel: true, // 开启并行压缩
exclude: /node_modules/,
}),
3. 代码分离
通过将公共代码或者第三方库依赖提取出来好处有多个:
- 可以有效的减少重复打包代码,减少打包体积
- 第三方库基本不变,减少重复打包次数
- 减少bundle体积,加快资源加载
具体配置内容:
splitChunks: {
// 分块策略(common chunk strategy)
// priority 优先级
cacheGroups: {
// loadsh: {
// test: /[\\/]node_modules[\\/](loadsh)[\\/]/,
// name: 'loadsh',
// chunks: 'initial',
// priority: -30,
// },
// react: {
// test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/,
// name: 'react',
// chunks: 'initial',
// priority: -40,
// },
vendors: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'initial',
priority: -50,
reuseExistingChunk: true,
},
commons: {
name: 'commons',
chunks: 'initial',
minChunks: 2,
priority: -60,
reuseExistingChunk: true,
},
}
},
4. css抽离
通过配置mini-css-extract-plugin,将css抽取到独立的css文件中,然后通过link的方式引入。
npm i mini-css-extract-plugin -D
具体配置如下:
new MiniCssExtractPlugin({
filename: '[name].[contenthash:8].css',
chunkFilename: '[id].css',
}),
5. 外部依赖扩展
将一些体积大、不需要修改的第三方库单独剥离,而不是打包到bundle中去,然后通过cdn引入,提升打包速度的同时,优化资源加载体验。
具体配置:
externals: {
'react': 'React',
'react-dom': 'ReactDOM',
'loadsh': '_',
},
6. tree sharking
通过webpack内置的tree sharking对无用的代码进行剔除。通过在package.json中配置sideEffects来标记文件为副作用。
注意,所有导入文件都会受到 tree shaking 的影响。这意味着,如果在项目中使用类似
css-loader并 import 一个 CSS 文件,则需要将其添加到 side effect 列表中,以免在生产模式中无意中将它删除
具体配置:
"sideEffects": [
"**/*.scss"
]
提升打包速度
1. 打包速度查看工具
speed-measure-webpack-plugin: 测量webpack构建速度。
效果如下:
2. 控制loader的打包范围
loader 支持通过配置 test、include和exclude属性来控制打包范围,有效级依次为 exclude > include > test;
我个人倾向于配置exclude, 具体配置以 babel-loader 为例:
{
test: /\.(t|j)sx?$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
cacheDirectory: true, // 开启 babel-loader 缓存
},
},
]
}
3. 忽略依赖
通过配置 noParse,防止 webpack 解析那些任何与给定正则表达式相匹配的文件。忽略的文件中 不应该含有 import, require, define 的调用,或任何其他导入机制。
具体配置:
noParse: /react|react-dom|lodash/,
4. 配置缓存
- webpack5提供了 cache 属性,缓存生成的 webpack 模块和 chunk,来改善构建速度。
具体配置:
cache: {
type: 'filesystem',
compression: 'gzip',
},
- babel-loader 配置 cacheDirectory
cacheDirectory: true
5. 开启多线程
- 通过使用 thread-loader 来开启多进程,将耗时的 loader 放在一个独立的 worker 池中运行,加快 loader 构建速度。
项目体积不大的话,不建议配置thread-loader开启多进程
以babel-loader为例,具体配置如下:
test: /\.(t|j)sx?$/,
exclude: /node_modules/,
use: [
"thread-loader",
{
loader: 'babel-loader',
options: {
cacheDirectory: true, // 开启 babel-loader 缓存
},
},
]
}
- 通过配置happypack开启多个子进程进行编译,来提升打包速度
不建议使用,相关库已不维护
webpack内置打包优化
- Scope Hoisting
- 将模块代码内置,而不是包装在单独的闭包函数中
- 减少代码体积
- 提升代码运行速度
相关文章推荐: