Tree-Shaking

Author Avatar
via
发表:2025-10-08 15:29:00
修改:2026-04-08 15:31:06

Tree-Shaking 是前端工程化中一种用于消除无用代码(Dead Code) 的优化技术,其核心目的是在打包过程中剔除项目中未被使用的代码,从而减小最终输出文件的体积。

核心原理

Tree-Shaking 的实现依赖于 ESM(ECMAScript Module)的静态模块结构

  • ESM 采用 import/export 语法,模块依赖关系在编译时(静态分析阶段) 就能确定,而非运行时。

  • 工具(如 Webpack、Rollup、Vite 等)通过静态分析,识别出哪些导出的变量/函数从未被导入使用,这些就是“无用代码”。

  • 最终打包时,这些未被使用的代码会被直接剔除,如同从树上摇掉枯叶(“摇树”因此得名)。

关键前提

  1. 必须使用 ESM
    CJS(CommonJS)是运行时动态加载(require 可写在条件语句中),无法在编译时确定依赖关系,因此不支持 Tree-Shaking

  2. 代码需处于“严格模式”语境
    ESM 模块默认运行在严格模式下,避免了一些动态语法(如 eval、修改 arguments 等)对静态分析的干扰。

  3. 导出需为“具名导出”(Named Export)
    默认导出(export default)通常是一个对象,工具难以精确判断对象内部哪些属性未被使用,因此 Tree-Shaking 对具名导出的优化更彻底。

示例说明

假设存在一个模块 utils.js

// utils.js(ESM)
export const add = (a, b) => a + b;
export const minus = (a, b) => a - b;

在另一个文件中仅导入 add

// app.js(ESM)
import { add } from './utils.js';
console.log(add(1, 2)); // 仅使用 add,未使用 minus

打包时,Tree-Shaking 会识别到 minus 未被使用,最终输出的代码中会剔除 minus 的定义,只保留 add 相关逻辑。

实际应用中的注意事项

  1. 工具配置

    • Webpack 需在 mode: 'production' 下自动启用 Tree-Shaking(开发环境默认不开启,避免影响构建速度)。

    • Rollup/Vite 天生对 ESM 支持更好,Tree-Shaking 优化更彻底。

  2. 避免副作用代码
    如果模块中存在“副作用”(如直接执行的代码、修改全局变量等),工具可能无法安全剔除该模块,需通过 /*#__PURE__*/ 注释标记纯函数,告诉工具“此代码无副作用,可安全删除”。

    示例:

    // 有副作用(无法被剔除)
    console.log('这行代码会执行');
    
    // 无副作用(可被 Tree-Shaking 剔除,若未被使用)
    /*#__PURE__*/ (() => {
      console.log('这行代码仅在函数被调用时执行');
    })();
    
  3. 第三方库的处理
    部分第三方库可能仍使用 CJS 格式,或包含大量副作用代码,导致 Tree-Shaking 无法生效。此时可选择 ESM 格式的库(如通过 package.jsonmodule 字段指定 ESM 入口)。

总结

Tree-Shaking 是基于 ESM 静态分析的代码优化技术,通过剔除未使用的代码显著减小打包体积,是现代前端工程化中提升性能的重要手段。其效果依赖于 ESM 的正确使用和工具的合理配置。

评论