Tree Shaking 需代码写法、模块结构和构建配置三者严格配合,依赖静态 ESM、禁用 CommonJS、正确导出/导入、声明副作用并验证生效。

Tree Shaking 不是“开了就生效”的开关,它依赖代码写法、模块结构和构建配置三者严格配合。实际项目中落地效果差,往往不是工具不支持,而是某一个环节破坏了静态可分析性。
用纯 ESM 语法,禁用 CommonJS 混用
Tree Shaking 只对 静态 import/export 生效。CommonJS(require/module.exports)在运行时才确定依赖,构建工具无法提前判断哪些导出被使用。
- 所有自定义模块必须用
export function xxx()或export const xxx =,避免export default { a, b }这种对象导出——它会让整个对象被视为一个不可拆分的单元 - 引入第三方库时,优先选
lodash-es而非lodash;用date-fns替代moment;检查其package.json是否有"module": "dist/index.esm.js" - 在 Babel 配置中关闭 ESM 转换:
@babel/preset-env设置modules: false,否则会把import编译成require,直接废掉 Tree Shaking
按需导入,避免全量引入
即使库本身支持 ESM,错误的引入方式也会让工具“看不见”你只用了其中一部分。
- 写
import { debounce, throttle } from 'lodash-es',而不是import _ from 'lodash-es' - 避免
import utils from './utils'(默认导入),改用具名导入:import { formatTime, parseUrl } from './utils' - 对大型 UI 库(如 Ant Design、Element Plus),配合插件(如
unplugin-vue-components或unplugin-auto-import)实现自动按需引入
显式声明副作用,防止误删
有些文件没有导出,但执行时会注入样式、修改全局或打日志——这类代码若未声明,会被当作“无用代码”直接剔除。
立即学习“Java免费学习笔记(深入)”;
- 在项目根目录
package.json中加字段:"sideEffects": false表示全项目无副作用;或更安全地写成数组:"sideEffects": ["*.css", "*.scss", "src/polyfill.js"] - 不要在模块顶层写
console.log('init')、document.addEventListener(...)或import './index.css'(CSS 默认视为有副作用,需列入sideEffects才保留) - 组件库的样式入口(如
import 'antd/dist/reset.css')务必确保路径出现在sideEffects列表里
验证是否真正生效
别靠感觉,要动手确认。很多团队以为开了 production 模式就自动生效,结果体积没变——可能根本没摇起来。
- 构建后打开产物文件(如
dist/assets/index.[hash].js),搜索一个你明确没引用的函数名,确认它不在里面 - 用
webpack-bundle-analyzer或 Vite 的build.report查看模块依赖图,观察未引用模块是否被标记为 “unused” - 临时加一行
import { unusedHelper } from './utils',再构建对比体积变化:如果体积不变,说明它已被摇掉;如果明显增大,说明之前就没摇成功


















