优化实战:代码分割、Tree Shaking、Dev Server 与生产构建
本节目标
- 用
optimization.splitChunks拆出公共依赖 - 开启 Tree Shaking 去掉没用到的导出
- 配置
webpack-dev-server做热更新开发
**代码分割(Code Splitting)**让「不会一起变的代码」分开打包,提升缓存命中。最常见的就是把 node_modules 里的第三方库单独拆成 vendors chunk:
// webpack.config.js(片段)
module.exports = {
optimization: {
splitChunks: {
chunks: 'all', // 对所有 chunk(含异步)做分割
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/, // 命中第三方依赖
name: 'vendors', // 单独打成一个 vendors.bundle.js
chunks: 'all',
},
},
},
},
}这样业务代码改动时,vendors.bundle.js(react 等)因内容不变而文件名不变,浏览器直接读缓存,不用重新下载。
Tree Shaking 是「摇掉没被引用的导出」:
// math.js 里导出了 add 和 sub,但只用到 add
export function add(a, b) { return a + b }
export function sub(a, b) { return a - b } // 没被 import → 会被摇掉
// main.js
import { add } from './math.js'
console.log(add(1, 2))前提是:① 用 ESM(import/export)② package.json 里 "sideEffects": false ③ mode: 'production'(开发模式默认不摇)。满足条件后,sub 不会进最终 bundle。
开发服务器让你免手动刷新:
# npm i -D webpack-dev-servermodule.exports = {
devServer: {
static: './dist',
port: 3000,
hot: true, // 热更新(HMR)
open: true, // 自动打开浏览器
},
}跑 npx webpack serve 即可边改边看。最后,区分开发与生产通常用两份配置或 mode 切换:开发用 webpack-dev-server + mode: 'development',生产用 npx webpack + mode: 'production'(自动压缩 + tree-shaking + splitChunks)。
名词解释
代码分割(Code Splitting):把代码按「变化频率 / 来源」拆成多个 bundle,让不常变的(如第三方库)能被长期缓存,提升加载性能。
splitChunks:Webpack 的自动拆包配置,cacheGroups 里用正则把 node_modules 等归到同一 chunk。
Tree Shaking(摇树):基于 ESM 的静态分析,移除「从未被 import 的导出」,减小 bundle 体积。需 sideEffects: false + 生产模式。
HMR(热模块替换):改代码后只局部刷新变化的模块,不整页刷新,开发体验飞起。devServer.hot: true 开启。
课后练习
练习 1:为什么 Tree Shaking 要求 ESM 而不是 CommonJS?
答案:ESM 的
import/export是「静态、可在编译期确定谁引用了谁」;CommonJS 的require()是运行时动态调用,无法静态分析哪些导出被用了。所以摇树只能对 ESM 生效。
练习 2:splitChunks.chunks: 'all' 和 'async' 区别?
答案:
'async'只分割动态import()的异步 chunk;'all'同时覆盖同步入口和异步 chunk,拆包更彻底。多数项目用'all'收益最大。
总结
Webpack 优化的三板斧——splitChunks 拆公共依赖(缓存友好)、Tree Shaking 摇掉死代码(体积友好)、dev-server 热更新(体验友好)。它们互不冲突,可以一起上:生产构建里 splitChunks + mode:production 自动带来拆包与摇树,开发时用 webpack-dev-server 提速。到这里,你从「为什么需要打包器」一路走到「手写插件 + 生产优化」,Webpack 的主干已经打通。下一步建议:挑一个真实小项目,把本课程的 8 节串起来完整跑一遍。