Tree Shaking 生效需 Babel 保留 ES 模块语法(设 "modules": false)、使用 ESM 版本库(如 lodash-es)、Webpack 开启 production 模式及 usedExports、concatenateModules 和 sideEffects 配置,并通过 source-map-explorer 验证未用代码是否被剔除。

Tree Shaking 要真正生效,Babel 不能把 ES 模块语法(import/export)转成 CommonJS(require/module.exports),否则打包工具就无法做静态分析。配合的关键在于让 Babel “保留原生模块结构”,再由 Webpack 或 Rollup 在后续阶段执行摇树。
确保 Babel 不转换模块语法
Babel 默认会把 import 编译为 require,这直接破坏 Tree Shaking 的前提。必须显式关闭模块转换:
- 在
.babelrc或babel.config.js中设置"modules": false - 推荐完整配置示例:
{"presets": [["@babel/preset-env", {"modules": false}]]} - 若使用 TypeScript,也要确认
tsconfig.json中"module": "ESNext",且babel-loader不覆盖该行为
统一使用 ES 模块路径导入
即使 Babel 配置正确,如果代码里混用 require、动态 import() 或 UMD 版本库,Tree Shaking 也会失效:
- 避免
const _ = require('lodash');改用import { debounce } from 'lodash-es' - 第三方库优先选带
-es后缀的版本(如lodash-es、date-fns),它们导出的是纯 ESM - 不要直接引用
node_modules/lodash/lodash.js这类 UMD 入口文件
Webpack 需同步启用关键优化项
Babel 只负责“不破坏模块结构”,真正执行摇树的是 Webpack。二者需协同:
立即学习“Java免费学习笔记(深入)”;
-
mode: 'production'必须开启——这是触发usedExports和压缩的前提 - 显式配置
optimization.usedExports: true,标记未使用的导出 -
optimization.concatenateModules: true(即 Scope Hoisting)可进一步合并模块,提升摇树精度 - 在
package.json中声明"sideEffects": false或精确列出有副作用的文件(如 CSS、JSON),否则 Webpack 不敢删除看似未引用的模块
验证是否真正生效
配置完不能只看体积数字,要确认“没被用的代码确实没进包”:
- 构建后用
source-map-explorer dist/js/main.js查看实际包含哪些模块 - 检查 bundle 中是否存在只被导入但从未调用的函数(比如
export const unusedHelper = () => {...}) - 对比开发模式与生产模式的产物差异,未摇掉的部分往往暴露了副作用声明缺失或动态导入干扰


















