分析依赖树,找出哪些模块占用了较多的资源。
npm install --save-dev webpack-bundle-analyzer
webpack.config.js中添加插件配置:
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
module.exports = {
// 其他配置项
plugins: [
// 其他插件
new BundleAnalyzerPlugin({
analyzerMode: 'static', // 生成静态报告文件
openAnalyzer: false, // 构建完成后不会自动打开报告
reportFilename: 'bundle-report.html' // 报告文件的名称
})
]
};
打包完成后,dist文件中多出bundle-report.html
文件,打开可以看到依赖占比。
通过使用缓存,能够有效提升打包速度。
webpack5 内置了 cache 模块,缓存生成的 webpack 模块和 chunk,来改善构建速度。
在开发环境下,默认设置为 type: 'memory'
而在生产环境中被禁用。cache: { type: 'memory' }
与 cache: true
作用一样,可以通过设置 cache: { type: 'filesystem' }
来开放更多配置项。
module.exports = {
cache: {
type: 'filesystem',
},
};
会在 node_modules 目录下生成一个 .cache 目录缓存文件内容,二次打包速度显著提升。
安装
npm install cache-loader -D
在 webpack.config.js 对应的开销大的 loader 前加上 cache-loader。
注意:如果使用多线程加载器如 thread-loader 时,也需要确保 cache-loader 放在 thread-loader 之前。
module.exports = {
module: {
rules: [
{
test: /\.js$/,
use: [
'cache-loader',
'babel-loader'
]
}
]
}
}
同时开启多个 nodejs 进程进行构建
yarn add thread-loader -D
module.exports = {
module: {
rules: [
{
test: /.js$/,
include: path.resolve('src'),
use: [
"thread-loader",
// 耗时的 loader (例如 babel-loader)
],
},
],
},
};
注意:
使用时,需将此 loader 放置在其他 loader 之前,放置在此 loader 之后的 loader 会在一个独立的 worker 池中运行。
每个 worker 都是一个独立的 node.js 进程,开销大约为 600ms 左右。同时会限制跨进程的数据交换。所以请仅在耗时的操作中使用此 loader!(一般只在大型项目中的 ts、js 文件使用)
代替 cdn 分包,解决每个模块都得引用一个 script 的缺陷。
以 react 和 react-dom 为例,新建一个 webpack.dll.js 文件,用于预编译资源的打包,例如要对 react 和 react-dom 进行预编译,配置如下:
const path = require('path');
const webpack = require('webpack');
module.exports = {
mode: 'production',
entry: {
library: ['react', 'react-dom'],
},
output: {
filename: 'react-library.dll.js',
path: path.resolve(__dirname, './dll'),
library: '[name]_[hash]', // 对应的包映射名
},
plugins: [
new webpack.DllPlugin({
context: __dirname,
name: '[name]_[hash]', // 引用的包映射名
path: path.join(__dirname, './dll/react-library.json'),
}),
],
};
package.json
中新增命令
{
// ...
"scripts": {
// ...
"build:dll": "webpack --config ./webpack.dll.js"
},
// ...
}
执行 npm run build:dll
后,webpack.config.js中:
const webpack = require('webpack');
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');
module.exports = {
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./dll/react-library.json'),
}),
// 打包后的 .dll.js 文件需要引入到 html中,可以通过 add-asset-html-webpack-plugin 插件自动引入
new AddAssetHtmlPlugin({
filepath: require.resolve('./dll/react-library.dll.js'),
publicPath: '',
}),
],
};
在 package.json 中添加 sideEffects 字段。
这个字段用于告知 Webpack,哪些文件或模块是无副作用的,哪些可能有副作用。
{
"name": "your-project",
"version": "1.0.0",
"sideEffects": false
}
false
表示项目中所有模块都没有副作用,因此未使用的代码可以被安全地移除。
如果某些模块有副作用,可以用数组的形式列出这些模块:
{
"sideEffects": ["./src/someSideEffectFile.js"]
}