tree shaking 是依赖 es6 模块静态分析的代码消除技术,需代码写法(具名导出、无副作用)、构建配置(production 模式、sideeffects 精确设置)和依赖选型(esm 版本、按需引入)三者协同才能生效。

Tree Shaking 不是“开了就自动变小”的开关,而是需要代码写法、构建配置、依赖选型三者协同生效的系统性实践。它真正起效的关键,在于让构建工具能**静态确认哪些导出从未被引用**——这要求你从模块定义到引入方式,每一步都符合它的分析逻辑。
确保模块结构支持静态分析
Tree Shaking 的前提是 ES 模块的静态性。任何动态行为都会打断分析链,导致整块代码被保留。
- 所有自定义模块必须用具名导出:✅ export function foo() 或 ✅ export const bar = 123;避免 ❌ export default { foo, bar } 这类对象式默认导出
- 禁止在模块顶层执行副作用代码:比如直接调用函数、修改全局变量、console.log()、new Date() 等。这些会让 Webpack 默认认为该模块“有副作用”,不敢轻易摇掉
- 第三方库要选支持 ESM 的版本:例如用 lodash-es 替代 lodash,用 @ant-design/icons/es 替代完整包;检查其 package.json 是否包含 "module": "dist/es/index.js"
正确引入,避免“整包卡死”
即使库本身支持 Tree Shaking,错误的引入方式也会让它完全失效。
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
- 禁用命名空间导入:❌ import * as _ from 'lodash-es' 或 ❌ import _ from 'lodash-es' —— 这会触发全量引用,摇树机制直接放弃分析
- 坚持具名按需导入:✅ import { debounce, throttle } from 'lodash-es'
- 组件库优先走子路径或具名导入:✅ import Button from '@uiw/react-button' 或 ✅ import { DatePicker } from 'antd';不推荐 ❌ import { DatePicker } from 'antd/lib/date-picker'(已过时且路径不稳定)
构建配置必须精准到位
Webpack/Vite/Rollup 默认在 production 模式下启用 Tree Shaking,但几个关键配置极易被忽略或误设。
- 确认 mode: 'production' 已设置(Webpack);Vite 无需额外开启,但若用了 build.rollupOptions.treeshake,请确保值为 true 或未被覆盖
- package.json 中的 "sideEffects" 字段不能写 true:❌ "sideEffects": true 表示“所有文件都有副作用”,等于关掉 Tree Shaking;应设为 ✅ "sideEffects": false(全无副作用),或精确列出:✅ "sideEffects": ["*.css", "index.js"]
- Babel 用户注意:@babel/preset-env 默认会把 import 编译成 require,必须显式关闭:"modules": false
验证是否真的生效
别靠感觉,用产物说话。体积数字变化最直观,但也要看内容是否真被剔除。
- 用 webpack-bundle-analyzer 可视化分析打包结果,定位某个工具函数是否出现在最终 chunk 中
- 临时加一行未使用的导入:import { unusedHelper } from './utils';,然后对比两次构建的体积差——如果没变化,说明摇树没起作用
- 直接查看 dist 目录下的 JS 文件,搜索某个明确未调用的函数名(如 subtract),确认其函数体是否还存在










