javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > Webpack Rollup Tree-shakin实现

Webpack 与 Rollup 中 Tree-shaking 的实现原理与效果

作者:拉不动的猪

Tree-shaking是现代前端构建工具中用于消除死代码的重要优化手段,本文就来介绍一下Webpack 与 Rollup 中 Tree-shaking 的实现原理与效果,具有一定的参考价值,感兴趣的可以了解一下

Tree-shaking 是现代前端构建工具中用于消除死代码(未被使用的代码)的重要优化手段,核心原理是利用 ES6 模块的静态特性(import/export)分析代码依赖,剔除未被引用的导出内容。

一、Tree-shaking 核心前提

Tree-shaking 仅对 ES6 模块(ESM)  有效,因为 ESM 具有以下静态特性:

CommonJS 模块(require/module.exports)因依赖关系动态化,无法被 Tree-shaking 优化。

二、Rollup 中的 Tree-shaking

Rollup 是专注于 ES 模块打包的工具,Tree-shaking 是其原生核心功能,实现简洁且高效。

1. 实现原理

Rollup 通过以下步骤实现 Tree-shaking:

  1. 依赖解析:遍历模块的 import/export 语句,构建模块依赖图。
  2. 标记未使用代码:从入口模块出发,追踪所有被引用的导出(export),未被引用的导出被标记为 “死代码”。
  3. 删除死代码:在打包阶段直接剔除标记的死代码,不生成冗余内容。

Rollup 对代码的静态分析更彻底,且默认输出未被混淆的代码,因此 Tree-shaking 效果直观可见。

2. 代码示例与效果

源文件

// utils.js(ES 模块)
export const add = (a, b) => a + b;
export const minus = (a, b) => a - b; // 未被使用的函数

// index.js(入口文件)
import { add } from './utils.js';
console.log(add(1, 2)); // 仅使用 add

Rollup 配置(rollup.config.js)

export default {
  input: 'src/index.js',
  output: {
    file: 'dist/bundle.js',
    format: 'es' // 输出 ES 模块(保留 import/export,便于观察)
  }
};

打包结果(dist/bundle.js)

const add = (a, b) => a + b;
console.log(add(1, 2));

三、Webpack 中的 Tree-shaking

Webpack 从 v2 开始支持 Tree-shaking,但实现逻辑更复杂,受多种因素影响(如模式、压缩工具等)。

1. 实现原理

Webpack 的 Tree-shaking 分为三个阶段:

  1. 标记阶段

    • 解析 ES 模块的 import/export,通过 ModuleConcatenationPlugin 分析模块依赖。
    • 对未被引用的导出标记为 /* unused harmony export xxx */(仅标记,不删除)。
  2. 删除阶段

    • 依赖 压缩工具(如 Terser)  剔除标记的死代码。
    • 仅在 production 模式下默认启用(开发模式为保留代码不删除)。
  3. 副作用处理

    • 通过 package.json 的 sideEffects 字段标记模块是否有副作用(如全局变量修改、DOM 操作),避免误删有副作用的代码。

2. 代码示例与效果

源文件(同 Rollup 示例)

// utils.js
export const add = (a, b) => a + b;
export const minus = (a, b) => a - b; // 未被使用

// index.js
import { add } from './utils.js';
console.log(add(1, 2));

Webpack 配置(webpack.config.js)

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  mode: 'production' // 必须为 production 模式才会删除死代码
};

打包结果(dist/bundle.js,简化后)

console.log(3); // add(1,2) 被直接计算,minus 完全删除

3. 关键配置:sideEffects

如果模块存在副作用(如修改全局变量),需在 package.json 中声明,避免被误删:

json

{
  "sideEffects": [
    "./src/polyfill.js", // 有副作用的模块
    "*.css" // CSS 文件通常有副作用(插入样式)
  ]
}

四、核心差异对比

特性RollupWebpack
分析能力原生支持 ESM 静态分析,更彻底需依赖插件(ModuleConcatenationPlugin),分析逻辑较复杂
删除死代码时机打包阶段直接删除依赖压缩工具(Terser)在优化阶段删除
开发模式效果即使开发模式也会删除死代码仅 production 模式删除(开发模式保留用于调试)
输出可读性输出代码接近源码,Tree-shaking 效果直观输出代码经压缩混淆,效果需反推
适用场景库文件打包(如工具库、组件库)应用程序打包(依赖复杂、需处理多种模块类型)

五、总结

六、直观点

到此这篇关于Webpack 与 Rollup 中 Tree-shaking 的实现原理与效果的文章就介绍到这了,更多相关Webpack Rollup Tree-shakin实现内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文