tree shaking 起效需代码(es6模块、无副作用)、依赖(esm版本)、配置(production模式+sideeffects声明)三方协同,否则静态分析失效。

要让 Tree Shaking 真正起作用、显著减小打包产物,关键不是“开了开关”就行,而是从代码写法、依赖管理、构建配置三方面协同配合。它不自动生效,也不对所有代码一视同仁。
确保代码使用 ES6 模块语法
Tree Shaking 的基础是静态可分析性。只有 import/export 能在构建时明确知道谁导出了什么、谁引入了什么;require/module.exports 是运行时动态的,工具无法判断哪些部分没被用到,直接绕过摇树。
- 自己写的模块全部用
export和import { xxx },避免import * as utils或import utils from '...'这类全量引入 - 第三方库优先选提供 ESM 版本的,比如用
lodash-es替代lodash,查 package.json 里是否有"module"字段 - 别在模块顶层写执行逻辑(如直接调用函数、修改全局变量),这会触发副作用,导致整块模块无法被摇掉
正确配置构建工具的生产环境与副作用声明
Webpack、Vite、Rollup 默认只在 production 模式 下启用 Tree Shaking。同时,它们需要你明确告诉它:“哪些文件改了全局状态,不能乱删”。
- 确保构建命令用了
--mode production(Webpack)或启用了 Vite 的 build 模式 - 在项目根目录
package.json中添加"sideEffects"字段:-
"sideEffects": false:表示整个项目无副作用,未引用的 export 全部可删(最激进,适合纯函数库) -
"sideEffects": ["./src/polyfill.js", "*.css"]:只保留列出的文件(如 CSS 注入、polyfill 执行),其余按需摇树
-
- 避免在组件或工具模块中写
console.log、localStorage.setItem、new Audio()这类有隐式副作用的语句,否则整块模块可能被保留
避免常见破坏 Tree Shaking 的写法
即使配置全对,几行看似无害的代码也可能让 Tree Shaking 失效。
-
不要解构导入后再赋值给新变量:
const { add } = require('./math')是 CommonJS,且解构赋值属于运行时行为,无法静态分析 -
不要动态拼接 import 路径:
import(`./pages/${page}.js`)是动态 import,Tree Shaking 对其内部不分析 -
不要把导出对象挂到 this 或 window 上:例如
export const init = () => { window.MyLib = {...} },这会让工具认为该模块有外部影响,不敢删除 -
避免默认导出混合命名导出:有些旧库用
export default { foo, bar },这种结构难以精确标记单个方法是否被使用
验证是否真的生效
别只信配置,要用工具看结果。
- 用
webpack-bundle-analyzer或 Vite 的rollup-plugin-visualizer生成依赖图,检查未使用的工具函数、组件是否还出现在最终 chunk 里 - 临时把某个导出函数改成
export function unused() { alert('I am dead') },再打包,如果产物里还有这个字符串,说明 Tree Shaking 没覆盖到那里 - 对比 development 和 production 构建后的 JS 文件大小差异,明显缩小(尤其在大量工具函数场景下)才是有效信号
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











