一、什么是 Tree Shaking?
Tree Shaking 是一种通过静态分析移除 JavaScript 中未使用代码的优化技术。其名称源自“摇树”动作——摇掉树上未成熟的果实(未使用的代码)。可以减小打包文件的体积,提高加载性能
二、核心原理
-
静态分析
- 在编译阶段分析代码的
import/export
依赖关系。 - 识别未被引用的模块或函数。
- 在编译阶段分析代码的
-
标记未使用代码
- 通过
/*#__PURE__*/
标记无副作用的函数调用。 - 结合
package.json
的"sideEffects"
字段排除副作用模块。
- 通过
-
移除死代码
- 在压缩阶段(如 Terser)移除标记为未使用的代码。
Tree shaking的工作流程可以分为
1.标记哪些导出值没有被使用; 2. 使用Terser将这些没用到的导出语句删除
标记的流程如下:
make阶段:收集模块导出变量并记录到模块依赖关系图中
seal阶段:遍历模块依赖关系图并标记那些导出变量有没有被使用
构建阶段:利用Terser将没有被用到的导出语句删除
三、实现条件
-
使用 ES 模块
- 代码必须使用
import/export
语法(CommonJS 不支持 Tree Shaking)。
- 代码必须使用
-
配置生产模式
- Webpack 的
mode
设置为production
,默认启用 Tree Shaking。
- Webpack 的
-
标记副作用
- 在
package.json
中声明无副作用的模块:{ "sideEffects": false // 或指定有副作用的文件 ["*.css", "*.scss"] }
- 在
四、Webpack 配置
-
启用 Tree Shaking
module.exports = { mode: 'production', // 生产模式默认启用 optimization: { usedExports: true, // 标记未使用的导出 启动 minimize: true // 压缩时移除未使用代码 } };
-
标记无副作用函数
/*#__PURE__*/ someFunction(); // 标记为无副作用
五、验证 Tree Shaking 效果
-
检查打包结果
- 使用
webpack-bundle-analyzer
分析打包文件,确认未使用代码被移除。
- 使用
-
查看 Terser 日志
- 启用
TerserPlugin
的extractComments
选项,查看移除的代码。
- 启用
六、注意事项
-
避免副作用
- 确保模块的导入不会触发副作用(如全局变量修改)。
-
第三方库支持
- 确保第三方库提供 ES 模块版本(如
lodash-es
)。
- 确保第三方库提供 ES 模块版本(如
-
Babel 配置
- 避免 Babel 将 ES 模块转换为 CommonJS(设置
modules: false
):{ "presets": [["@babel/preset-env", { "modules": false }]] }
- 避免 Babel 将 ES 模块转换为 CommonJS(设置
通过以上配置和优化,可有效实现 Tree Shaking,减少打包体积,提升应用性能。