webpack 构建优化
这篇主要介绍四类 webpack 构建优化方法,分别是:
- 缩小查找范围
- 减少打包文件
- 缓存
- 多进程
缩小查找范围
使用 loader 时给定具体范围: include
module.exports = {
module: {
rules: [
{
test: /\.js$/,
use: {
loader:'babel-loader'
},
include: [
path.resolve(__dirname, 'src')
],
}
}
}
使用 module.noParse 让某些非 AMD/CommonJS 模块不参与解析
module.exports = {
module: {
noParse: /jquery|lodash/
}
};
使用 resolve.alias 缩短包的查找过程
module.exports = {
resolve: {
'vue$': 'vue/dist/vue.esm.js',
}
};
使用 resolve.modules 缩短包目标位置的查找过程
module.exports = {
resolve: {
modules: [
path.resolve(__dirname,'src')
path.resolve(__dirname, 'node_modules'),
]
}
};
使用 resolve.mainFields 缩短包在 package.json 中的 main 字段的查找过程
module.exports = {
resolve: {
mainFields: ['main', 'module']
}
};
减少打包文件
使用 optimzation.splitChunks 分割出公共代码
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name:'vendor',
priority: 10,
}
}
}
}
};
使用DllPlugin 和 DllReferencePlugin 动态链接基本不改变的包
// webpack.dll.config.js
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: {
vendor: ['vue', 'lodash'], // 需要打包 的第三方库
},
output: {
path: path.resolve(__dirname,'dist'),
filename: 'dll.vendor.js',
library: 'vendor_library',
},
plugins: [
new webpack.DllPlugin({
name: 'vendor_library',
path: path.resolve(__dirname, 'dist', 'vendor-manifest.json'),
}),
],
};
通过 webpack --config webpack.dll.config.js 打包出 dll 文件
然后在主配置中使用 DllReferencePlugin 引用
// webpack.config.js
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
},
plugins: [
new webpack.DllReferencePlugin({
manifest: require('./dist/vendor-manifest.json'),
}),
],
};
<!-- 还需要在模板中引入 dll 文件 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 引入动态链接文件 -->
<script src="./vendor/vendor.dll.js"></script>
</body>
</html>
使用 externals 排除不必打包的文件库
module.exports = {
externals: {
vue: 'Vue',
lodash: '_',
$: 'jquery',
jQuery: 'jquery',
}
};
利用 tree-shaking 机制减小打包文件
- 优先使用 ESM 模块的包,引入时只引入需要的方法
缓存
使用 cache-loader 缓存编译结果
module.exports = {
module: {
rules: [
{
test: /\.js$/,
use: [{
loader: 'cache-loader',
}, {
loader: 'babel-loader',
}]
}
]
}
};
使用 hard-source-webpack-plugin 缓存编译结果
这个插件可以缓存编译结果,并且在编译过程中,会将编译结果缓存到硬盘中,下次编译时,会优先读取缓存结果,加快编译速度。可以跨 dev 和 build 共享缓存
module.exports = {
plugins: [
new HardSourceWebpackPlugin(),
]
};
多进程
使用 happypack 多进程打包
const HappyPack = require('happypack');
module.exports = {
module: {
rules: [
{
test: /\.js$/,
// 开启多进程打包
use: 'happypack/loader?id=js',
}
]
},
plugins: [
new HappyPack({
id: 'js',
loaders: ['babel-loader'],
})
]
}
使用 thread-loader 多进程打包
module.exports = {
module: {
rules: [
{
test: /\.js$/,
use: [
'thread-loader',
'babel-loader'
]
}
]
}
};