JS中实现打包时自动剔除未使用代码的核心是Tree Shaking,它依赖ES模块静态分析、无副作用声明、生产模式配置及库的合理导出结构。

JS 中实现打包时自动剔除未使用的死代码,核心靠的是 Tree Shaking,它本质是死代码消除(DCE)在模块化构建中的具体应用。关键不在于手动删代码,而在于让打包工具能“看懂”哪些导出没被用,并安全地移除它们。
必须使用 ES 模块语法(import/export)
Tree Shaking 依赖静态可分析的模块结构。CommonJS(require/module.exports)是运行时动态加载,打包工具无法在编译期确定哪些导出被使用。
- ✅ 正确写法:
export const add = () => {}+import { add } from './math.js' - ❌ 无效写法:
module.exports = { add }或import * as math from './math.cjs'
确保模块没有副作用(sideEffects)
即使某个模块没被显式 import,如果它有副作用(比如向 window 添加属性、执行 fetch、修改全局样式),打包工具会保守保留整个模块,导致 Tree Shaking 失效。
- 在
package.json中声明:"sideEffects": false(表示全包无副作用) - 若只有部分文件有副作用(如 CSS、SVG),可精确列出:
"sideEffects": ["*.css", "*.scss"] - 避免在模块顶层写执行逻辑,例如:
console.log('init')或document.body.classList.add('loaded')
启用生产模式与相关配置
现代打包工具默认在生产模式下开启 Tree Shaking,但需确认关键开关已就位:
- Webpack:设
mode: 'production'即可自动启用;也可显式配置:optimization.usedExports: true(标记导出使用情况) - Rollup/Vite:默认开启,无需额外配置,但需确保输入是 ESM 格式
- 注意:
dynamic import()是运行时行为,其导入的模块无法被静态分析,因此不能触发对目标模块内部函数的 Tree Shaking
库作者需提供可摇树的导出结构
如果你开发的是供他人使用的 UI 库或工具库,要支持下游用户按需引入,就得设计好导出方式:
- 入口文件(
index.js)用命名导出:export { Button, Card, Modal },而非export default { Button, Card } - 避免“聚合导出”破坏摇树,例如不要写:
export * from './utils'(除非 utils 内部也支持摇树) - 推荐采用“逐文件导出”+“入口索引转发”,便于工具精确追踪引用路径











