Tree Shaking是JavaScript构建流程中用于剔除未使用代码的优化技术,核心目标是减少最终打包文件的体积,提升应用的加载性能。它最早由Rollup构建工具提出,现在已经被Webpack、Vite等主流构建工具广泛支持,是前端项目优化的重要环节。

Tree Shaking的核心依赖:ES模块的静态特性
Tree Shaking能够生效的前提是代码使用ES模块规范编写,因为ES模块具备静态分析能力,和CommonJS的动态特性有本质区别:
- ES模块的导入导出语句必须写在模块的顶层作用域,不能在条件判断、函数内部动态声明
- 导入的模块路径必须是静态字符串,不能使用变量拼接路径
- 导入的绑定是活绑定的,指向原模块的导出值,且导入的变量是只读的
这些特性让构建工具在编译阶段就能明确知道模块的依赖关系,以及每个模块导出了哪些内容、导入了哪些内容,不需要执行代码就能完成分析,这是Tree Shaking能够实现的基础。
Tree Shaking的完整工作流程
构建工具执行Tree Shaking通常分为三个核心步骤:
1. 标记模块导出
构建工具首先会遍历所有模块的导入导出语句,记录每个模块的所有导出项,以及这些导出项被哪些模块导入使用。比如下面的模块代码:
// utils.js
export const add = (a, b) => a + b;
export const minus = (a, b) => a - b;
export const multiply = (a, b) => a * b;
// main.js
import { add } from './utils.js';
console.log(add(1, 2));
分析后工具会知道utils.js导出了三个方法,其中只有add被main.js导入使用,minus和multiply属于未被使用的导出。
2. 识别副作用代码
构建工具会判断模块是否有副作用,副作用指的是模块执行时除了导出内容之外,还会产生其他影响,比如修改全局变量、操作DOM、发送请求等。如果模块有副作用,即使它的导出没有被使用,也不能直接被剔除。
可以在package.json中通过sideEffects字段声明模块是否有副作用:
{
"sideEffects": false
}
如果设置为false,说明所有模块都没有副作用,构建工具可以放心剔除未使用的导出。如果是数组形式,比如["*.css"],说明只有匹配数组规则的模块有副作用,其他模块无副作用。
3. 剔除无用代码
完成标记和副作用判断后,构建工具会把所有未被使用且没有副作用的模块导出从最终的打包产物中移除,然后配合代码压缩工具比如Terser,进一步删除无用的变量和语句,完成最终的优化。
影响Tree Shaking效果的常见问题
实际开发中很多情况会导致Tree Shaking失效,需要注意规避:
- 使用CommonJS的
require、module.exports导入导出,因为CommonJS是动态加载,无法静态分析 - 导入全部导出内容,比如
import * as utils from './utils.js',构建工具无法判断哪些导出被使用,会保留所有内容 - 模块存在未声明的副作用,比如模块中直接执行了
document.body.appendChild(...)这类操作,又没有在sideEffects中声明,可能导致优化异常 - 使用Babel转译代码时,如果Babel把ES模块转成了CommonJS模块,会直接破坏Tree Shaking的基础,需要配置Babel不转换模块语法
Webpack中Tree Shaking的配置示例
在Webpack中开启Tree Shaking需要保证模式是production,因为production模式默认开启了相关优化,同时需要正确配置:
// webpack.config.js
module.exports = {
mode: 'production',
optimization: {
usedExports: true, // 标记被使用的导出
}
};
同时需要在package.json中配置sideEffects:
{
"sideEffects": ["*.css", "*.scss"]
}
这样Webpack就会对除了CSS、SCSS之外的模块执行Tree Shaking优化,剔除未使用的导出代码。
总结
Tree Shaking的本质是利用ES模块的静态特性,在构建阶段分析代码的依赖关系,识别并剔除未被使用的无副作用代码,最终减小打包体积。要发挥Tree Shaking的最大效果,需要坚持使用ES模块规范编写代码,正确配置sideEffects字段,避免CommonJS混用和不必要的全量导入,同时保证构建工具的模块转译配置不会破坏ES模块的静态结构。
Tree_ShakingJavaScript构建优化ES模块副作用代码压缩修改时间:2026-07-06 03:39:21