优化实战:代码分割、Tree Shaking、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-server
module.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 节串起来完整跑一遍。