Tree Shaking 是一种通过静态分析剔除未使用代码的构建优化技术,应用于 Webpack、Rollup 和 Vite 等工具,依赖 ES6 模块的静态结构,在打包时移除“死代码”,减小文件体积。其原理是基于 AST 分析 import/export 依赖关系,从入口文件标记并保留被引用的代码,删除未使用的导出。为确保生效,应使用 ES6 模块语法,避免副作用,并在 package.json 中设置 "sideEffects": false 或指定必要文件。需注意它不支持 CommonJS 模块,且生产模式下才完全启用,开发环境通常保留全部代码以便调试。

Tree Shaking 并不是 JavaScript 本身的特性,而是一种在构建阶段通过静态分析代码来剔除未使用模块的优化技术。它广泛应用于现代前端构建工具中,如 Webpack、Rollup 和 Vite,目标是减小打包后的文件体积,提升应用加载性能。
什么是 Tree Shaking
Tree Shaking 的名字来源于“摇动一棵树,枯叶掉落,留下有用的枝叶”。在代码构建过程中,它会把整个项目看作一棵依赖树,只保留被实际引用的函数或变量,移除那些定义了但从未被调用的“死代码”(dead code)。
这项技术主要适用于 ES6 模块(import / export),因为这种模块结构是静态的,可以在编译时确定哪些导出被使用,哪些没有。
实现原理:静态分析与标记机制
Tree Shaking 能够工作的核心在于 ES 模块的静态结构:
立即学习“Java免费学习笔记(深入)”;
- ES6 的 import 和 export 必须写在顶层,不能动态嵌套在条件语句中
- 导入和导出关系在代码执行前就可以被解析
- 构建工具可以基于 AST(抽象语法树)进行静态分析,找出未被引用的导出
具体流程如下:
- 构建工具扫描所有模块,建立 import/export 的依赖图
- 从入口文件开始,标记所有被实际使用的导出(称为“活代码”)
- 未被标记的导出被视为可安全删除的“死代码”
- 最终生成的包中不包含这些未使用的代码
如何确保 Tree Shaking 生效
虽然大多数现代构建工具默认支持 Tree Shaking,但一些编码方式会阻碍其正常工作。以下几点能帮助你最大化利用该优化:
- 使用 ES6 模块语法,避免 require() 或动态导入混淆静态分析
- 避免给模块添加副作用(side effect),比如在模块顶层执行非声明性操作
- 在 package.json 中正确设置 "sideEffects": false,告诉打包工具可以安全地移除未引用的模块
- 如果某些文件必须保留(如 polyfill),可通过数组形式列出:"sideEffects": ["./src/polyfill.js"]
常见误区与限制
Tree Shaking 不是万能的,有几个关键限制需要注意:
- 对 CommonJS 模块(module.exports / require)无效,因其动态特性无法静态分析
- 如果一个函数被导入但从未调用,它会被移除;但如果被赋值给变量或传入高阶函数,可能仍被保留
- 副作用代码(如修改全局对象、注册事件监听)可能导致模块无法被摇掉,即使未显式使用
- 生产模式下才启用完整 Tree Shaking,开发环境通常为调试方便保留全部代码
基本上就这些。只要保持模块化、使用静态导入导出,并合理配置 sideEffects,Tree Shaking 就能在构建时自动帮你瘦身代码包。不复杂但容易忽略细节。










