验证工具类库Tree Shaking干净度需确认未引用命名导出是否被完全剔除,核心是使用ESM静态导出、禁用副作用、构建后用Bundle Analyzer等工具检查残留代码。

要验证工具类库在 JavaScript Tree Shaking 中的“摇树干净度”,核心是确认未被引用的导出(尤其是命名导出)是否真能被构建工具(如 Webpack、Rollup、Vite)完全剔除,而非因副作用、导出方式或模块格式问题残留。
检查导出方式是否支持静态分析
Tree Shaking 依赖 ES Module 的静态结构。确保你的工具库使用 ESM 原生语法导出,避免混合 CommonJS 或动态导出:
- ✅ 推荐:每个工具函数单独命名导出(
export function debounce(...)),或统一对象导出后解构(export const { throttle, debounce } = utils,但需确保utils本身可被追踪) - ❌ 避免:
module.exports = { debounce, throttle }、export default { debounce, throttle }(默认导出对象会阻断摇树)、export * from './debounce.js'(若目标文件有副作用或非纯 ESM) - ⚠️ 注意:TypeScript 编译时需设置
module: "ESNext"和isolatedModules: false(否则可能降级为 CommonJS)
构建后检查产物中是否存在未引用代码
不依赖肉眼扫包,用工具定位残留:
- Webpack:启用
optimization.usedExports: true+devtool: 'source-map',再用 Webpack Bundle Analyzer 查看模块依赖图,筛选你库的入口文件,展开看哪些导出被标记为unused export - Rollup/Vite:构建时加
--format es --sourcemap,然后用 rollup-plugin-visualizer 或直接查看生成的.map文件对应源码位置 —— 若某函数在最终 bundle 里仍存在且未被调用,说明未被摇掉 - 小技巧:在库中给每个工具函数加唯一注释(如
// [debounce]),构建后全局搜索该字符串,快速判断是否残留
模拟最小消费场景做隔离验证
写一个极简测试入口,只引入并使用一个函数,再构建观察结果:
立即学习“Java免费学习笔记(深入)”;
- 新建
test-entry.js:import { throttle } from 'your-utils'; throttle(() => {}, 300); - 确保构建配置禁用
sideEffects: true(应设为false或精确列出有副作用的文件,如['*.css']) - 构建后反查 bundle:若
debounce、once等其他函数代码完全不存在,说明摇树有效;若仍有,检查它们是否被间接引用(比如某个函数内部import了另一个、或有顶层执行逻辑)
警惕隐式副作用和“假干净”
即使代码没执行,某些写法也会让打包器保守保留:
- 导出对象含 getter / setter / 构造函数调用(如
export const A = new Class()) - 模块顶层有 console / localStorage / DOM 操作等(即使没被调用,也被视为有副作用)
-
package.json中未声明"sideEffects": false(或未精确声明),导致整个模块被当作有副作用而跳过摇树 - 类型导出(
export type)不影响运行时,但若混在值导出中(如export { type Foo, bar }),部分工具链可能误判
验证摇树不是一劳永逸的事——每次新增导出、调整打包配置或升级构建工具版本后,都建议回归跑一次最小消费构建+产物扫描。干净的摇树,本质是导出可推断、无副作用、模块格式纯粹的结果。


















