关键是要在package.json中声明sideEffects: false或精确列出有副作用的文件,确保模块无顶层副作用,并配合/#__PURE__/注释辅助压缩器移除无副作用调用,最终通过构建产物验证未使用导出是否被标记为unused harmony export并消失。

要在 JavaScript Tree Shaking 中让模块被安全“摇掉”,关键不是在代码里加开关,而是向打包工具明确传达:这个模块没有副作用。否则,即使函数没被引用,工具也会保守保留整块代码。
在 package.json 中统一声明 sideEffects
这是最常用也最推荐的方式,作用于整个包:
- "sideEffects": false —— 表示所有 JS 文件都无副作用(纯计算、无全局修改、无 DOM 操作、无网络请求),打包器可放心剔除未引用的导出
- "sideEffects": ["*.css", "*.scss", "src/init.js"] —— 只列出真正有副作用的文件或资源类型,其余 JS 模块默认可摇
- 不写该字段,或设为 true,等同于告诉工具“每个文件都可能有副作用”,Tree Shaking 基本失效
避免模块顶层执行副作用代码
即使声明了 sideEffects: false,若模块顶部直接运行代码,仍会破坏摇树效果:
- ❌ 错误写法:模块一加载就执行
console.log('init')、Object.assign(window, {...})、document.addEventListener(...) - ✅ 正确做法:把副作用逻辑封装进函数,再按需调用;或移入单独文件(如
src/polyfill.js),并在sideEffects数组中显式保留 - 例如:
export function initPolyfill() { ... }+/*#__PURE__*/ initPolyfill()(配合压缩阶段优化)
单文件内用 /*#__PURE__*/ 注释标记调用
该注释不改变模块是否被保留,但能辅助压缩器(如 Terser)在最终阶段移除或内联特定调用:
立即学习“Java免费学习笔记(深入)”;
- 必须紧贴函数调用左侧,中间不能换行:
/*#__PURE__*/ doCalc(1, 2) - 仅适用于真正无副作用的场景:纯数学运算、
console.log(仅日志)、简单常量初始化 - ⚠️ 注意:它不解决模块级保留问题,必须和
sideEffects配合使用才完整
验证是否生效
别只看配置,要检查输出结果:
- 构建后打开 bundle 文件,搜索未使用的函数名,确认不存在
- Webpack 用户可查是否有
/* unused harmony export xxx */标记 - 用
rollup-plugin-visualizer或webpack-bundle-analyzer查依赖图,观察未引用模块是否消失


















