Tree Shaking 起效关键在于模块设计:需用具名导出、拆分模块、杜绝顶层副作用、明确声明 sideEffects。默认导出对象、聚合入口、副作用代码及错误 sideEffects 配置均会阻碍摇树。

要让 Tree Shaking 真正起效,模块设计本身比构建配置更关键。工具只能“识别”未使用代码,而能否被识别,取决于你如何组织和导出功能。
用具名导出替代默认导出对象
Tree Shaking 只能按“导出项”粒度删除,不能拆解一个对象内部的属性。如果把多个函数打包进一个默认导出对象,哪怕只用其中一个,整个对象都会保留。
- ✅ 推荐写法(每个函数独立可摇):
export const debounce = () => { ... };
export const throttle = () => { ... }; - ❌ 避免写法(整块无法摇):
export default { debounce: ..., throttle: ... };
拆分模块,避免聚合入口文件
一个大的 index.js 把所有功能 re-export 出来,容易让打包器误判依赖关系,尤其当其中某些导出来自有副作用的子模块时。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 保持模块职责单一:比如
math/add.js、math/sub.js各自导出一个函数 - 入口文件只做轻量转发:
export { add } from './math/add';
export { sub } from './math/sub'; - 不建议在入口里执行逻辑或引入 CSS/初始化脚本
杜绝顶层副作用,保持模块“纯净”
只要模块顶层有副作用(比如直接调用函数、修改 window、发请求、console.log),打包器就会认为它“不可安全删除”,进而保留整个文件,即使你只 import 了其中某个函数。
立即学习“Java免费学习笔记(深入)”;
- 副作用操作一律移到函数体内或调用处
- 避免导出可变变量:export let count = 0; → 改为 export const getCount = () => count;
- 移除
eval()、with、Function构造等动态特性
明确声明 sideEffects 并精准控制
在 package.json 中设置 "sideEffects" 不是可选项,而是告诉打包器“哪些文件必须保留”。设错会导致样式丢失或初始化失败。
- 纯工具库可设 "sideEffects": false
- 含 CSS 或 polyfill 的项目应显式列出:
"sideEffects": ["*.css", "*.scss", "src/init.js"] - 不要留空或写
"sideEffects": true,这等于关闭 Tree Shaking

















