要实现打包时自动裁剪未使用的 class 静态方法,需将其改为独立具名函数并显式导出,配合 /#__PURE__/ 标注、生产模式及正确 tree-shaking 配置,避免动态访问和副作用干扰。

要实现在打包阶段自动裁剪 class 中未使用的静态方法,核心在于利用现代 JavaScript 工具链的**死代码消除(Dead Code Elimination, DCE)能力**,而非单纯依赖语法层面的 tree-shaking。静态方法能否被裁剪,取决于它们是否被**可静态分析的、具名的、无副作用的导出与引用模式**所包裹。直接写在 class 内部的 static method 若未被单独导出或未满足 ES 模块规范下的引用条件,绝大多数 bundler(如 Webpack、Rollup、Vite)默认无法安全移除。
确保静态方法以独立导出函数形式存在
Tree-shaking 本质作用于“导出单元”,而非 class 成员。即使方法是 static,只要它只是 class 的一部分,且 class 本身被引用(哪怕只用了一个实例方法),整个 class 就可能被保留。
- 将每个需参与裁剪的静态逻辑拆为独立的具名函数,并用
export显式导出 - 避免仅通过
MyClass.staticMethod方式调用;改用import { staticMethod } from './utils.js' - 示例:
❌ 不利于裁剪:export class Utils { static formatTime() { ... } }
✅ 支持裁剪:export function formatTime() { ... }
启用严格的模块解析与纯函数标注
让打包器识别“该函数无副作用”,才能放心移除未调用分支。
- 在函数顶部添加
/*#__PURE__*/注释(尤其对创建对象/调用副作用函数的静态方法) - 确保构建配置中
mode: 'production'且optimization.usedExports: true(Webpack)或treeshake: { moduleSideEffects: false }(Rollup) - Vite 用户需确认
build.treeshake = true(默认开启),并避免在package.json中设置"sideEffects": true
避免破坏静态分析的常见陷阱
以下写法会阻断 tree-shaking,导致静态方法无法被识别为可裁剪单元:
- 使用动态属性访问:
MyClass['formatTime']()或const m = 'formatTime'; MyClass[m]() - 将 class 作为整体导出:
export { MyClass },而非按需导出其静态成员 - 静态方法内部调用了全局变量、
console、localStorage等有副作用的操作,且未标注/*#__PURE__*/ - 使用 Babel 编译时启用了
@babel/preset-env默认的loose: true模式,可能破坏 export 形式 —— 建议设为loose: false并启用modules: false
验证裁剪结果是否生效
不能只信配置,要观测输出产物。
- 使用
rollup-plugin-visualizer(Rollup/Vite)或webpack-bundle-analyzer查看实际保留的函数 - 检查生成的
.mjs或.js文件,搜索目标静态方法名,确认未出现在最终 bundle 中 - 开启 Webpack 的
stats: 'verbose',观察usedExports是否标记为false(表示已被剔除)

















