webpack中文文档:webpack.docschina.org/configurati…
1. 多入口配置?
webpack.common.js:
const srcPath = path.join(__dirname, '..', 'src')
const distPath = path.join(__dirname, '..', 'dist')
entry: {
index: path.join(srcPath, 'index.js'),
main: path.join(srcPath, 'main.js')
},
plugins: [
new HtmlWebpackPlugin({
template: path.join(srcPath, 'index.html'),
filename: 'index.html',
chunks: ['index']
}),
new HtmlWebpackPlugin({
template: path.join(srcPath, 'main.html'),
filename: 'main.html',
chunks: ['main']
})
]
webpack.prod.js:
output: {
filename: '[name].[contentHash:8].js',:index 、main
path: path.join(__dirname, '..', 'dist'),
}
2. 如何抽离公共代码和第三方代码?
optimization.splitChunks进行分割代码块optimization.splitChunks.cacheGroups做缓存分组:第三方模块、公共模块
optimization: {
splitChunks: {
chunks: 'all',
// 缓存分组
cacheGroups: {
// 第三方模块
vendor: {
name: 'vendor',
priority: 1, // 优先级
test: /node_modules/,
minSize: 1024,
minChunks: 1
},
// 公共的模块
common: {
name: 'common',
priority: 0,
minSize: 1024,
minChunks: 2 // 引用两次则抽离
}
}
}
}
3. 性能优化-打包构建速度?
babel-loader优化IgnorePlugin避免引入无用模块noParse避免重复打包happyPack多进程打包工具ParalleUglifyPlugin多进程打包压缩DLLPlugin- 热更新
(1) 优化babel-loader
webpack.dev.js:
module: {
rules: [{
test: /\.js$/,
loader: ['babel-loader?cacheDirectory'],
include: path.join(__dirname, '..', 'src'),
exclude: /node_modules/
},
]
}
(2) IgnorePlugin忽略无用模块
webpack.prod.js:
plugins: [
new webpack.IgnorePlugin(/\.\/locale/, /moment/)
]
(3) noParse避免重复打包
如vue.min.js已经模块化处理过了,需要忽略对此类型文件的打包。
webpack.prod.js:
rules: [{
test: /\.vue$/,
loader: ['vue-loader'],
include: path.join(__dirname, '..', 'src')
}]
IgnorePlugin vs noParse
IgnorePlugin直接忽略掉,减少了产出代码体积;noParse不被打包;
(4) happyPack
js是单线程的,开启多线程打包,可提高构建速度(特别是多核CPU)
module: {
rules: [{
test: /\.js$/,
use: ['happypack/loader?id=babel'],
include: path.join(__dirname, '..', 'src'),
}]
},
plugins: [
new HappyPack({
id: 'babel',
loaders: ['babel-loader?cacheDirectory']
})
]
(5) ParalleUglifyPlugin多进程压缩JS
- 开发环境下没必要使用;
- 项目大、打包慢,开启多进程能提高速度;
- 项目小、打包快,开启多进程会降低速度;
plugins: [
new ParallelUglifyPlugin({
uglifyJS: {
output: {
beautify: false,
comments: false
},
compress: {
drop_console: true,
collapse_vars: true,
reduce_vars: true
}
}
})
]
(6) DllPlugin
使用背景:
- 前端框架如Vue、React,体积大,编译慢;
- 较稳定,不常升级版本;
- 同一个版本只需构建一次,不用每次都重新构建;
DLLPlugin将常用框架打包成dll文件再引用,webpack5已内置DLLPlugin支持:
step 1: DLLPlugin打包出dll文件:
<1> 单独配置webpack.dll.js,用于生成dll文件(DllPlugin插件):
const DllPlugin = require('webpack/lib/DllPlugin')
module.exports = {
entry: {
react: ['react', 'react-dom']
},
output: {
filename: '[name].dll.js',
path: path.join(__dirname, '..', 'dist'),
library: '_dll_[name]'
},
plugins: [
new DllPlugin({
name: '_dll_[name]',
path: path.join(distPath, '[name].manifest.json'),
})
]
}
<2> 在package.json配置dll命令,并运行:npm run dll:
script: {
"dll": "webpack --config ./build/webpack.dll.js"
}
step 2: DllReferencePlugin 使用 dll 文件:
<1> 配置webpack.dev.js:
const DllReferencePlugin = require('webpack/lib/DllReferencePlugin')
module: {
rules: [
{
test: /\.js$/,
loader: ['babel-loader'],
include: path.join(__dirname, '..', 'src'),
exclude: /node_modules/
}
]
}
<2> index.html 里引用 react.dll.js:
<script src="./react.dll.js"></script>
(7) 热更新
const HotModuleReplacementPlugin = require('webpack/lib/HotModuleReplacementPlugin')
// devServer.hot: true
entry: {
index: [
'webpack-dev-server/client?http://localhost:3000/',
'webpack/hot/dev-server',
path.join(srcPath, 'index.js')
],
main: path.join(srcPath, 'main.js')
},
plugins: [new HotModuleReplacementPlugin()]
// main.js 入口文件 开启热更新之后的代码逻辑
if (module.hot) {
module.hot.accept(['./test'], () => {
console.log('test in hot...')
})
}