Tree Shaking 是构建阶段的静态分析优化,需满足ES6模块、无副作用、颗粒化导出三条件;CommonJS会阻断分析,须用lodash-es等ESM库,配置sideEffects和构建工具启用。

Tree Shaking 不是运行时优化,而是在构建阶段通过静态分析剔除未使用的代码。它真正起效的前提不是“写了模块”,而是整个链路满足静态可分析、无干扰副作用、导出方式可粒度识别这三个关键条件。
必须用 ES6 模块语法(import/export)
CommonJS 的 require 是动态的,无法在编译期确定加载了什么,所以 Tree Shaking 对它完全无效。哪怕只有一处 require(moduleName) 或 module.exports = {...},就可能阻断整条依赖链的摇树分析。
- 所有源码、第三方库(或其打包产物)都应使用
import和export - 避免混用:比如在 ES 模块中
import xxx from 'lodash',但 lodash 内部用 CommonJS 导出,就无法摇掉未用函数——需确认该库提供了 ESM 版本(如 lodash-es) - 检查 node_modules 中依赖的入口文件是否指向
"module"字段(package.json 中),而非"main"
导出要颗粒化,优先命名导出
默认导出(export default)把多个功能包裹成一个整体对象,工具无法判断其中哪个方法被用、哪个没被用,自然无法剔除。
- 写工具函数时,用
export const fnA = () => {}、export function fnB() {} - 避免
export default { fnA, fnB }这类聚合导出 - 按需导入:用
import { fnA } from './utils',而不是import utils from './utils'
显式声明副作用,避免误删
有些代码虽然没被“引用”,但执行后会影响环境(比如注入全局样式、注册事件、修改 window 属性),这类代码叫“有副作用”。打包工具为安全起见,默认保留它们——除非你明确告诉它:“这个文件/目录没有副作用”。
立即学习“Java免费学习笔记(深入)”;
- 在项目根目录
package.json中添加"sideEffects"字段 - 纯逻辑模块(无 DOM 操作、无样式、无全局变量修改)可设为
"sideEffects": false - 若只有部分文件有副作用(如 CSS、SVG、polyfill),列出它们:
"sideEffects": ["*.css", "*.scss", "src/polyfills.js"]
确保构建工具启用并正确配置
Tree Shaking 不是自动全开的魔法,需要构建工具主动开启分析,并配合压缩器最终移除代码。
- Webpack:启用
mode: 'production'即默认激活;也可显式加optimization.usedExports: true - Vite / Next.js:生产构建(
vite build/next build)默认启用,无需额外配置 - Rollup:默认深度摇树,但需确保
output.format设为'es'(保留 ESM 结构) - 压缩阶段也要配合:Terser 需开启
compress: { unused: true, dead_code: true }


















