面试题:项目中做过哪些 webpack 打包优化?分两类:构建速度优化 、打包产物体积优化
🚀构建速度优化(打包变快)
- exclude排除node_modules,不要编译第三方库,节省大量时间
- babel-loader 开启cacheDiretory缓存
- thread-loader 多线程
- 配置resolve的extensions缩小查找范围,配置alias别名避免向上遍历,配置modules只找本项目的node_modules
- dev环境下不使用terser压缩
- dev环境下使用cheap-source-map
- 合理的devtools
- dev环境不使用minicssextraplugin 剥离css,不contenthash
📦产物体积优化(包变小),也就是减小首屏体积的优化
- 分包 + contenthash 浏览器强缓存
- 懒加载异步分包
- splitChunks 公共模块抽离 同步分包
- runtimeChunk:single webpack 运行时分包
- minicssextraplugin 抽离css
- 压缩:js 压缩 TerserPlugin;css 压缩 CssMinimizerPlugin
- 资源压缩,小图片转base64,大的转文件, 或者提前压缩
- 第三方库按需引入,找体积合适的
- 生产环境tree-shanking 删除无用代码 基于ESM
- 通过判断环境配置生产环境excludes 大库,html里手动引入cdn
js
// webpack.config.js
const path = require('path')
const TerserPlugin = require('terser-webpack-plugin')
const isDev = process.env.NODE_ENV === 'development'
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js',
chunkFilename: '[name].[contenthash].chunk.js',
clean: true
},
module: {
rules: [
{
test: /\.js$/,
// ✅关键1:exclude排除node_modules,不要编译第三方库,节省大量时间
exclude: /node_modules/,
use: [
// ✅大项目开启多线程编译,小项目不要开(线程有创建开销)
{
loader: 'thread-loader',
options: { workers: 2 }
},
{
loader: 'babel-loader',
options: {
// ✅开启babel缓存,二次构建复用缓存,不用重复编译
cacheDirectory: true
}
}
]
},
{
test: /\.css$/,
use: isDev ? ['style-loader', 'css-loader'] : ['mini-css-extract-plugin.loader', 'css-loader']
}
]
},
resolve: {
// ✅减少后缀尝试的数量,加快模块查找
extensions: ['.js', '.vue'],
// ✅别名,减少向上递归查找文件
alias: {
'@': path.resolve(__dirname, './src')
}
},
// ✅开发环境用快的source‑map,不要完整源码映射
devtool: isDev ? 'cheap-module-eval-source-map' : 'source-map',
optimization: {
// 生产才压缩,开发关闭压缩,极大提升dev启动速度
minimizer: isDev ? [] : [new TerserPlugin()],
splitChunks: { chunks: 'all' },
runtimeChunk: 'single'
}
}