最直接有效的方式是结合产物检查与体积对比,双轨验证 Tree Shaking 是否真正起效——既看“删没删”,也看“删多少”。手动检查打包产物中的未使用导出,用 webpack-bundle-analyzer 可视化分析模块导出引用状态,并通过临时引入再移除未使用导出的对照实验量化裁剪体积。

最直接有效的方式是结合产物检查与体积对比,双轨验证 Tree Shaking 是否真正起效——既看“删没删”,也看“删多少”。
手动检查打包产物中的未使用导出
打开构建后生成的最终 JS 文件(如 dist/main.js 或 dist/bundle.js),用编辑器搜索你明确未引用的函数、类或常量名:
- 若某个 export function helper() 在项目中从未被 import 过,但在 bundle 中仍能完整搜到其函数体,说明 Tree Shaking 未生效
- 若搜索结果为空,再进一步查找 Webpack 标记:搜索 /* unused harmony export —— 出现该注释说明已识别但尚未删除;若连注释都没有,大概率已被 Terser 彻底移除
- 注意排除干扰:确保没通过 window.xxx = xxx、console.log(xxx) 或 CSS 导入等方式意外触发副作用保留
用 webpack-bundle-analyzer 可视化分析
这是最直观的验证手段,能清晰看到模块内部哪些导出被保留、哪些被裁掉:
- 安装插件:npm install --save-dev webpack-bundle-analyzer
- 在 webpack 配置的 plugins 中加入 BundleAnalyzerPlugin
- 运行生产构建并启动分析:npx webpack --mode=production --stats=verbose && npx webpack-bundle-analyzer dist/stats.json
- 浏览器打开后,点击目标模块(如 utils.js),右侧会显示“Exports”列表——只被标记为 used 的才保留在输出中;若某导出旁标着 not used 却仍占体积,就需排查副作用或语法问题
量化裁剪效果:引入对照实验
不靠猜测,用体积变化说话。操作简单但结论可靠:
- 在入口文件(如 index.js)中临时添加一行未使用的导入:import { unusedFn } from './helpers';
- 执行构建:npm run build,记录产物总大小(如 main.js: 124.8 KB)
- 注释掉那行导入,再次构建,对比新体积(如 main.js: 123.2 KB)——差值 1.6 KB 就是 Tree Shaking 实际裁掉的部分
- 可重复多轮:分别测试不同工具函数、组件、常量,汇总裁剪总量,评估优化收益
确认构建配置是否启用关键开关
即使代码写得规范,配置缺失也会让 Tree Shaking 形同虚设:
- Webpack:确保 mode: "production",且未覆盖 optimization.usedExports: true 和 optimization.innerGraph: true
- Vite / Next.js:默认开启,但需检查是否误启了 legacy 模式或自定义 rollupOptions 关闭了 treeshake: true
- package.json 中的 "sideEffects" 必须准确:设为 false 表示无副作用;若含 CSS 或 polyfill,应显式列出:["*.css", "*.scss", "index.js"]
- Babel 用户需确认 @babel/preset-env 的 modules 选项为 false,避免把 import 编译成 require











