tree shaking 需严格依赖 es6 模块语法、正确配置 sideeffects 及实证验证;混用 commonjs、错误导出、未声明副作用或动态引用均会导致失效。

Tree Shaking 不是自动生效的魔法,它依赖严格的代码结构和构建配置。写错一个导出、多加一行副作用、配错 sideEffects 字段,就可能让本该被摇掉的代码原封不动打进 bundle。
确保模块使用 ES6 静态导入/导出
Tree Shaking 只对 import/export 语法有效,不识别 require 或 module.exports。即使混用一点点(比如某个工具文件用了 CommonJS),整个模块链都可能失去摇树能力。
- 所有工具函数、组件、常量统一用
export const xxx、export default,避免export default { a, b }这种对象解构导出(它会被视为整体导出) - 导入时别写
import * as utils from './utils',除非你真用到了全部;优先用命名导入:import { debounce } from './utils' - 避免在
export前加运行时逻辑,例如export const foo = Math.random() > 0.5 ? 'a' : 'b'—— 这会让打包器保守保留
显式声明无副作用,别靠猜
package.json 中的 "sideEffects": false 表示整个包完全无副作用,但多数 UI 库或工具库并非如此:CSS 导入、全局 polyfill、console 日志、定时器初始化等都算副作用。
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
- 如果项目里只用 JS 模块(如纯函数工具库),可设为
false;否则列出明确有副作用的文件:["*.css", "*.scss", "index.js"] - 别把
sideEffects: false直接抄到业务项目根目录——你的入口文件main.js几乎一定有副作用(渲染、事件监听、路由挂载) - 第三方库若未正确声明
sideEffects,可在 Webpack 的resolve.alias或 Vite 的optimizeDeps.exclude中干预,或手动 patch
警惕“看似无用,实则被引用”的陷阱
有些代码看似没调用,却因静态分析无法判定而被保留。常见于高阶抽象、运行时路径、动态 key 访问等场景。
- 避免
obj[variable]或arr[index]引用导出成员,改用明确的命名导入 - 不要把导出变量作为参数传给高阶函数再间接调用(如
register(pluginA)),打包器通常无法追踪这类注册关系 - 类的装饰器、Vue/React 的 options API 中字符串形式的 method 名(如
methods: { handleClick }),若handleClick是导出函数,也可能逃过摇树
验证是否生效,别信感觉
光看打包体积下降不等于 Tree Shaking 生效——可能是压缩率提升或其它优化导致。必须定位到具体模块确认。
- Webpack 用户开启
stats: 'verbose',搜索unusedExports字段;或用source-map-explorer可视化分析产物 - Vite 用户运行
vite build --report生成report.html,展开模块依赖图,检查未引用的导出是否出现在最终 chunk 中 - 手动在源码中加一个明显标识(如
export const __TREE_SHAKING_TEST__ = 'this should disappear'),构建后搜产物文件验证是否真的没了
不复杂但容易忽略。核心就三条:用对语法、说清副作用、验得准结果。










