Tree Shaking 原理

1. 面试题

Q: 什么是 Tree Shaking?它的原理是什么?为什么必须使用 ESM (import/export)?

2. 核心解答

Tree Shaking (摇树优化) 是一种消除无用代码 (Dead Code Elimination) 的技术。

(1) 原理

Webpack 从入口文件开始建立依赖图,并在遍历时标记被导出的模块

  1. 静态分析:分析代码中的 importexport 语句,识别出哪些模块被导出了。
  2. 标记:对所有导出的模块打上标记。
  3. 消除:在构建打包阶段 (Minification Phase) 移除未使用的代码。如果一个模块没有被任何其他模块引用,则认为它是无用的。

(2) 必须使用 ESM

CommonJS (require/module.exports) 是动态的,难以进行静态分析。因为 CommonJS 可以在运行时动态加载模块 (require('./' + name) ),Webpack 无法确定到底引用了哪个文件,因此很难做 Tree Shaking。 而 ESM (import/export)静态的,必须位于顶层,不能嵌套在条件语句中。Webpack 可以在编译阶段 (Compile Time) 就确定模块的依赖关系,从而安全地移除无用代码。

(3) SideEffects

有些代码虽然没有导出任何变量,但具有副作用 (比如 polyfill, CSS 文件, 全局样式修改)。如果我们简单的把未引用的模块删了,可能会导致程序崩溃。 解决方案:在 package.json 中配置 "sideEffects": false (表示该包无副作用,可放心移除),或者数组形式列出有副作用的文件 ("sideEffects": ["*.css", "*.polyfill.js"])。这是告诉 Webpack:"虽然没用 export,但我干了坏事 (Side Effect),别删我!"。

3. 面试加分项

Q: Tree Shaking 是 Webpack 做的吗?

其实主要工作是在 UglifyJS / Terser (压缩工具) 中完成的。Webpack 负责标记 (Marking) (通过 unused harmony export 注释),而压缩工具负责删除 (Removal) (识别到标记后移除代码)。

4. 总结

  • Static Analysis: Based on ESM structure.
  • DCE: Dead Code Elimination.
  • SideEffects: Mark side-effect files to prevent removal.
  • Execution: By Terser/Uglify during minification, marked by Webpack.