tree shaking 不支持手动矫正误判,而是保守保留动态代码;可通过 /*#__pure__*/ 注释提示 terser 删除无副作用的函数调用,或用 /*#__no_side_effects__*/ 告知 rollup 当前模块无副作用,但注释不能替代对动态导入、条件导出等问题的根本修复。

Tree Shaking 本身不支持“手动矫正误判”,它依赖静态分析,而 JavaScript 的动态特性(比如运行时计算的 import 路径、条件导出、副作用表达式)会让打包工具无法确定某段代码是否真被使用——此时工具不是“误判”,而是**主动保守保留**,这是安全行为,不是 bug。
但你可以在关键位置用特定注释,向压缩器(如 Terser)传达“这段代码可被安全移除”的意图,从而在 删除阶段 起作用。这类注释只影响压缩器,不影响打包器的标记逻辑,也不是绕过静态分析的“矫正”,而是协助最终清除。
用 /*#__PURE__*/ 注释标记可摇函数调用
当某个函数调用没有副作用、且结果未被使用时,Terser 可能保留它(尤其在开发或非严格模式下)。加上 /*#__PURE__*/,就告诉压缩器:“这个调用可以被整个删掉”。
- 适用于顶层立即执行的纯函数,例如初始化逻辑中无副作用的辅助调用
- 写法必须紧贴函数调用,不能有换行或空格隔开
- 只对函数调用有效,不对变量声明或 class 定义起作用
✅ 正确示例:
/*#__PURE__*/ console.log('debug only');
/*#__PURE__*/ Math.random(); // 结果未赋值,且无副作用
❌ 无效写法:
/*#__PURE__*/
console.log('broken'); // 换行导致注释失效
const x = /*#__PURE__*/ someFn(); // 注释位置错误,Terser 不识别
用 /*#__NO_SIDE_EFFECTS__*/ 告知模块无副作用(仅 Rollup 支持)
Rollup 提供了更细粒度的提示:在模块顶部添加该注释,等效于 package.json 中的 "sideEffects": false,但作用范围限于当前文件。
- 必须放在文件最开头(可跟在 'use strict' 后,但不能有空行)
- 仅 Rollup 识别,Webpack 和 Vite 不处理此注释
- 适合临时标记一个尚未发布、也未配 sideEffects 字段的工具模块
示例:
/*#__NO_SIDE_EFFECTS__*/
export const add = (a, b) => a + b;
export const sub = (a, b) => a - b;
避免滥用注释替代根本修复
注释不能解决 Tree Shaking 失效的根本原因。如果打包工具连导出都没标记为 unused,说明静态分析已被破坏——这时加 /*#__PURE__*/ 也没用。
- 动态 import()、条件 export、CJS 混入、Babel 转译 export → 这些必须重构,注释无效
- 顶层 console.log、fetch、全局赋值 → 应移入函数内,或显式声明 sideEffects
- export default { fn1, fn2 } → 改为命名导出,注释救不了对象解构不可分析的问题
验证注释是否生效
构建后检查 dist 文件:
- 搜索
/*#__PURE__*/是否仍存在:若还在,说明 Terser 未启用或未匹配到可删节点 - 搜索被标记的调用内容(如 'debug only'):若已消失,说明注释起效
- 对比开启/关闭 Terser 的产物体积,确认是否有额外精简
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











