Tree Shaking 自然生效需用 ES 模块语法、生产模式构建、具名导出、精确导入、选用原生 ESM 第三方库,并正确声明 sideEffects;验证须借助可视化工具或手动检查产物。

直接用 ES 模块语法写,配好构建工具默认生产模式,再按需导入——Tree Shaking 就自然生效了。它不靠魔法,靠的是代码结构和工具链的默契配合。
用标准 import/export,别碰 require
Tree Shaking 依赖静态分析,只有 import 和 export 能被准确识别。CommonJS 的 require 和 module.exports 是运行时动态的,打包工具直接跳过,无法摇树。
- 导出要具名:用
export function foo()或export const bar = 1,别用export default { foo, bar } - 引入要精确:写
import { debounce } from 'lodash-es',而不是import _ from 'lodash-es' - 第三方库选对版本:用
lodash-es、date-fns这类原生 ESM 支持的包,避开普通lodash
构建配置保持默认生产模式
Webpack 5、Vite、Rollup 都在 production 模式下默认开启 Tree Shaking,多数情况下你不用额外配。
- Webpack:确认
mode: "production"已设,且没手动关掉optimization.usedExports - Vite:开箱即用,无需操作;若用了 legacy 插件或自定义
rollupOptions,检查treeshake: true - Babel 注意:如果用了
@babel/preset-env,设modules: false,防止把import编译成require
声明副作用,避免误删
有些文件虽无导出,但执行时会改全局、插样式、监听事件——这类“副作用”会让打包工具不敢删它。得主动告诉工具哪些文件安全可摇。
- 项目根目录
package.json中加"sideEffects": false,表示整个项目无副作用 - 如有例外(比如
main.css或polyfill.js),写成"sideEffects": ["*.css", "src/polyfill.js"] - 第三方库的
package.json若已声明sideEffects: false,就说明它专为 Tree Shaking 设计
验证效果,别只靠猜
体积变小了?不一定真摇掉了;构建日志说“usedExports enabled”?也不代表你的函数进了 bundle。动手验证才靠谱。
- 用
webpack-bundle-analyzer打开可视化报告,看目标函数是否出现在最终 chunk 里 - 临时加一行未使用导入:
import { unusedHelper } from './utils';,再对比构建后体积变化 - 打开生成的 JS 文件,搜索某个确定没调用的函数名,看它还在不在


















