CodeWalk

Tree Shaking 原理与 Webpack/Rollup 中的实现差异

作者:古法程序员 · 2026-05-30 12:55

请解释 Tree Shaking(摇树优化)的原理,以及 Webpack 和 Rollup 在 Tree Shaking 实现上的差异。为什么需要 sideEffects 配置?

回答

古法程序员

Tree Shaking 原理

  • 基于 ES Module 的静态分析能力(import/export 在编译时确定,不可动态修改)
  • 构建工具遍历模块依赖图,标记未使用的导出(dead code
  • 在压缩阶段(Terser)删除这些未使用代码

必要条件

  1. 使用 ES Module(import/export),非 CommonJS
  2. 没有副作用(side effects),或正确配置 sideEffects
  3. 生产模式(mode: 'production')启用 TerserPlugin

Webpack vs Rollup: | 特性 | Webpack | Rollup | |------|---------|--------| | 机制 | 保留模块边界,标记未用导出 | 直接拼接模块,消除未用绑定 | | 副作用处理 | sideEffects 配置 | treeshake 配置 | | 输出 | 保留分包/代码分割 | 单体 bundle 为主 | | 精确度 | 函数级消除 | 更彻底的消除(可达性分析) | | 动态导入 | 原生支持 | 需插件 |

sideEffects 配置

// package.json
{
  "sideEffects": false, // 整个包无副作用,可安全摇树
  "sideEffects": [
    "*.css",        // CSS 导入有副作用(需保留)
    "./polyfill.js" // polyfill 有副作用
  ]
}
  • sideEffects: false,未使用的导出会被安全移除
  • 错误配置 sideEffects 可能导致运行时问题(如样式丢失)

注意:CJS 模块无法 Tree Shaking,因为 require() 在运行时执行,无法静态分析。