Tree Shaking是一种基于ES模块静态结构特性的代码优化技术,它能在项目打包阶段自动剔除那些被导入但从未被实际使用的代码,减少最终产物的体积。这项技术的核心依赖就是静态分析能力,通过对代码结构的提前扫描判断代码的有效性。

Tree Shaking的核心原理
ES模块的静态特性是Tree Shaking生效的基础,ES模块的导入导出语句在代码编译阶段就能确定依赖关系,不需要等到运行时判断。静态分析就是在这个过程中完成对代码使用情况的标记:
- 首先扫描所有模块的导入导出声明,建立模块之间的依赖图谱
- 从入口文件开始遍历所有被引用的代码,标记出实际被使用的导出内容
- 最后在打包阶段,将未被标记的冗余代码从最终产物中移除
静态分析在Tree Shaking中的实现
静态分析需要在不执行代码的前提下,解析代码的语法结构。以JavaScript为例,分析流程通常包含词法分析和语法分析两个步骤:
1. 词法分析
将源代码拆分成一个个最小的语法单元,比如关键字、标识符、运算符等。例如下面的导入语句:
// 词法分析会将这行代码拆分为 import、{、utils、}、from、'./utils.js' 等单元
import { formatDate, calcSum } from './utils.js';
2. 语法分析
将词法分析得到的单元按照语法规则组合成抽象语法树(AST),通过AST可以清晰看到代码的导入导出关系。如果后续代码中只使用了formatDate,没有使用calcSum,那么calcSum就会在静态分析阶段被标记为未使用。
Webpack中Tree Shaking的配置示例
Webpack从2.0版本开始原生支持Tree Shaking,需要满足两个基础条件:模块使用ES模块语法、打包模式设置为production。下面是基础配置示例:
// webpack.config.js
module.exports = {
mode: 'production', // production模式会自动开启Tree Shaking相关优化
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: require('path').resolve(__dirname, 'dist')
},
optimization: {
usedExports: true // 标记未被使用的导出,配合压缩工具移除冗余代码
}
};
对应的工具模块代码和入口文件示例如下:
// src/utils.js 工具模块,导出两个方法
export const formatDate = (date) => {
return new Date(date).toLocaleDateString();
};
export const calcSum = (a, b) => {
return a + b;
};
// src/index.js 入口文件,只使用了formatDate
import { formatDate } from './utils.js';
console.log(formatDate(new Date()));
打包后,calcSum方法不会被包含到最终的bundle.js中,这就是静态分析配合Tree Shaking实现的效果。
注意事项
- 如果使用CommonJS的require、module.exports语法,Tree Shaking无法生效,因为CommonJS是动态加载的,无法在静态阶段确定依赖关系
- 如果导出的内容是对象,对对象属性的访问无法被静态分析识别,比如
export const obj = { a: 1, b: 2 },即使只使用了obj.a,obj.b也无法被移除 - 一些第三方库如果使用了副作用代码,需要在package.json中配置sideEffects字段来避免被误删
Tree Shaking的本质是静态分析能力的工程化应用,理解它的实现逻辑后,可以在项目打包优化中更合理地配置相关规则,避免冗余代码影响应用性能。
Tree_Shaking静态分析代码优化打包工具修改时间:2026-07-14 11:27:23