编程 Rspack 2.0 深度拆解:字节跳动如何用 Rust 重写 webpack——从 192 个依赖砍到 1 个,构建速度提升 15 倍的工程哲学

2026-08-03 12:13:19 +0800 CST views 14

Rspack 2.0 深度拆解:字节跳动如何用 Rust 重写 webpack——从 192 个依赖砍到 1 个,构建速度提升 15 倍的工程哲学

前言:webpack 十年之痛

2024 年 8 月,Rspack 1.0 正式发布。彼时,前端构建工具链正处于一个微妙的历史节点:webpack 已统治前端构建长达十年,但它的性能瓶颈已成为整个行业的痛点。一个包含 10000 个组件的 React 项目,webpack 的生产构建需要 28 秒,热更新需要 2.8 秒——对于追求极致开发体验的现代前端团队来说,这几乎是不可接受的。

与此同时,Vite 凭借原生 ESM 方案迅速崛起,esbuild 用 Go 语言证明了「用编译型语言重写 JS 工具」的可行性,Turbopack 宣称比 webpack 快 10 倍。在这场构建工具的军备竞赛中,字节跳动的 Web Infra 团队选择了一条独特的路径:不是推倒重来,而是在 webpack 的 API 之上,用 Rust 重写整个执行引擎

2026 年 7 月 29 日,Rspack 2.0 正式发布。这个版本不仅将依赖项从 192 个砍到了 1 个,还将构建性能再次提升 10%,更重要的是,它标志着 Rspack 从「webpack 的快速替代品」进化为「面向未来的现代 JavaScript 工具链」。

本文将从架构设计、核心机制、性能基准、生态布局四个维度,深度拆解 Rspack 2.0 的技术哲学。


一、架构设计:Rust + TypeScript 的双语言哲学

1.1 为什么选择 Rust 而不是 Go?

在「用编译型语言重写 JS 工具」的浪潮中,Rspack 选择了 Rust 而不是 Go(esbuild)或 Zig(Bun)。这个选择背后有着深刻的技术考量:

  • 内存安全:Rust 的所有权系统在编译期消除内存安全问题,这对于需要长时间运行的构建工具至关重要
  • 零成本抽象:Rust 的泛型和 trait 系统允许在不损失运行时性能的前提下构建高度抽象的架构
  • 并发安全:Rust 的 Send/Sync trait 系统使得并行化开发更加安全可靠
  • WASM 支持:Rust 到 WebAssembly 的编译路径成熟,为浏览器端构建提供了可能性

但 Rspack 并没有完全用 Rust 重写一切。它采用了一种务实的双语言架构

┌─────────────────────────────────────────────────┐
│                  TypeScript 层                    │
│  配置解析 · 插件系统 · 开发服务器 · JavaScript API │
├─────────────────────────────────────────────────┤
│                   NAPI-RS 桥接层                   │
├─────────────────────────────────────────────────┤
│                    Rust 核心层                     │
│  模块图构建 · 代码分割 · Tree Shaking · 压缩优化   │
│  SWC 转译 · 增量编译 · 持久化缓存 · 并行处理       │
└─────────────────────────────────────────────────┘

TypeScript 层负责开发者接触的所有接口——配置解析、插件系统、开发服务器。Rust 核心层则负责计算密集型的底层操作。两者通过 NAPI-RS 桥接,实现近乎零开销的跨语言调用。

1.2 SWC:Rspack 的转译引擎

Rspack 的转译能力直接复用了 SWC(Speedy Web Compiler),这也是一个 Rust 编写的 JavaScript/TypeScript 编译器。SWC 提供了:

  • JavaScript/TypeScript 转译:替代 Babel,速度提升 20-70 倍
  • JSX/TSX 支持:原生支持 React、Preact、Nerv 等框架的 JSX 语法
  • CSS 转译:通过 Lightning CSS 实现高速 CSS 处理和优化
  • Minification:SWC Minifier 替代 Terser,压缩速度提升数十倍

在 Rspack 2.0 中,SWC 的缓存机制得到了重大升级:开启持久化缓存后,SWC 压缩器可以复用缓存结果,构建性能提升约 50%,内存占用降低超过 20%

1.3 模块图构建:从入口到产物的完整链路

Rspack 的模块图构建流程遵循经典的打包器架构,但每个环节都经过了 Rust 级别的优化:

入口文件 (Entry)
    │
    ▼
┌─────────────┐     ┌──────────────┐
│  依赖解析    │────▶│  Loader 处理  │
│  (Resolve)  │     │  (Transform) │
└─────────────┘     └──────┬───────┘
                           │
                    ┌──────▼───────┐
                    │  模块图构建   │
                    │ (Module Graph)│
                    └──────┬───────┘
                           │
              ┌────────────┼────────────┐
              │            │            │
        ┌─────▼─────┐ ┌───▼───┐ ┌─────▼─────┐
        │ 代码分割   │ │ Tree  │ │  作用域    │
        │(Code Split)│ │Shaking│ │  提升      │
        └─────┬─────┘ └───┬───┘ └─────┬─────┘
              │            │            │
              └────────────┼────────────┘
                           │
                    ┌──────▼───────┐
                    │  代码生成     │
                    │ (Code Gen)   │
                    └──────┬───────┘
                           │
                    ┌──────▼───────┐
                    │  压缩优化     │
                    │(Minification)│
                    └──────────────┘

每个环节都支持并行化处理。Rspack 会自动将模块分组,在多个 worker 线程中并行构建模块图,充分利用多核 CPU 的计算能力。


二、Rspack 2.0 核心特性深度解析

2.1 依赖项大清洗:从 192 到 1

这是 Rspack 2.0 最令人印象深刻的改进之一。@rspack/dev-server 的依赖项从 192 个减少到了 1 个,安装大小从 15 MB 缩减至 1.4 MB。

这个数字在 Hacker News 上引起了广泛讨论。有评论者写道:

"与性能数据相比,依赖项减少的数字更让我印象深刻。这是一种理念的转变,而不仅仅是基准测试。在现阶段采取了比大多数打包工具更强硬的供应链立场。"

依赖项减少的实现策略包括:

1. 自研 dev-server,替换 webpack-dev-server

Rspack 1.x 的 dev-server 直接依赖 webpack-dev-server,后者又传递依赖了 Express 等大量包。Rspack 2.0 自研了轻量级的 dev-server 实现,使用 connect-next 替代 Express,保留了中间件模型的同时大幅减少了依赖。

2. 非核心依赖可选化

Module Federation 的运行时工具(@module-federation/runtime-tools)不再默认安装,只在用户实际使用 ModuleFederationPlugin 时才需要安装。

3. 依赖内联(Bundled Dependencies)

将部分依赖直接打包进 npm 包中,Rspack 可以完全控制这些依赖及其传递依赖的版本,减少因自动升级导致的供应链风险。

4. 优先使用 Node.js 原生 API

例如使用 Node.js 20+ 内置的 util.styleText() 替代 picocolors 库,减少不必要的外部依赖。

// Rspack 2.0 的 dev-server 配置示例
// 注意:不再需要单独安装 webpack-dev-server
import { defineConfig } from '@rspack/cli';

export default defineConfig({
  mode: 'development',
  devServer: {
    port: 3000,
    hot: true,
    // Rspack 2.0 自带 dev-server,无需额外依赖
  },
  // ...
});

2.2 纯 ESM 核心:告别 CommonJS 遗产

Rspack 2.0 的 @rspack/core 包现在作为纯 ESM 包发布,CommonJS 构建版本已被移除。

这个决定并非轻率之举。Node.js v20.19 及更高版本已经支持通过 require() 加载 ESM 模块,因此大多数使用 JavaScript API 的项目不需要修改代码。但对于使用旧版 Node.js 的项目,这是一个破坏性变更。

// Rspack 2.0 的 ESM 导入方式
import { rspack } from '@rspack/core';
import path from 'node:path';

const config = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.[contenthash].js',
  },
};

const compiler = rspack(config);
compiler.run((err, stats) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log(stats.toString({ colors: true }));
});

同时,Rspack 2.0 新增了对 import.meta 和 stage-3 import defer 提案的支持,为未来的 ESM 生态做好了准备。

2.3 构建性能:10000 组件项目的极致优化

Rspack 2.0 在 10000 个 React 组件的基准测试中表现如下:

版本生产构建(无缓存)生产构建(有缓存)HMR
Rspack 1.05.6s5.6s128ms
Rspack 1.73.6s2.2s134ms
Rspack 2.03.1s1.4s118ms

作为对比,webpack 在同一基准下的数据是 28.1s(生产构建)和 2.78s(HMR),Vite 是 1.98s(生产构建)和 130ms(HMR)。

性能提升的关键技术:

1. 持久化缓存(Persistent Cache)

Rspack 2.0 的持久化缓存不仅缓存模块的编译结果,还缓存 SWC 的压缩结果。当缓存命中时,构建性能提升约 50%。

2. 算法和数据结构优化

团队重构了关键性能路径上的算法和数据结构,升级了过时的依赖,并移除了未使用的代码路径。

3. 并行化架构的持续深化

Rspack 的 Rust 核心利用 Rayon 等库实现了细粒度的并行化。模块图构建、代码生成、压缩优化等阶段都可以在多个线程上并行执行。

// 开启持久化缓存的配置
import { defineConfig } from '@rspack/core';

export default defineConfig({
  cache: {
    type: 'filesystem',
    // Rspack 2.0 自动管理缓存目录和过期策略
    // 缓存命中时,SWC 压缩器也会复用缓存结果
  },
  // ...
});

2.4 Tree Shaking 增强:更智能的静态分析

Rspack 2.0 在静态分析方面做了显著改进,使得更多复杂代码模式能够受益于 Tree Shaking:

1. CommonJS require 解构识别

// 以前:Rspack 无法分析这种模式
const { useState, useEffect } = require('react');

// Rspack 2.0 现在可以识别实际使用的导出成员
// 并移除未使用的 useState 或 useEffect

2. 纯函数注解支持

通过 JSDoc 注解,开发者可以显式标记函数的副作用特性,帮助 Rspack 做出更激进的 Tree Shaking 决策:

/**
 * @pure
 * 这个函数没有副作用,未被使用时可以安全移除
 */
function computeValue(x) {
  return x * 2 + 1;
}

/**
 * @sideEffect
 * 这个函数有副作用,即使未被使用也不能移除
 */
function setupAnalytics() {
  window.__analytics = new Analytics();
}

3. Module Federation Tree Shaking

Module Federation 2.0 引入了共享依赖的 Tree Shaking 能力。当多个联邦应用共享同一个库时,Rspack 可以分析每个应用实际使用的导出,只打包必要的代码。

// Module Federation 配置示例
import { ModuleFederationPlugin } from '@module-federation/enhanced';

export default defineConfig({
  plugins: [
    new ModuleFederationPlugin({
      name: 'app1',
      remotes: {
        app2: 'app2@http://localhost:3001/remoteEntry.js',
      },
      shared: {
        // Rspack 2.0 会对共享依赖进行 Tree Shaking
        react: { singleton: true },
        'react-dom': { singleton: true },
      },
    }),
  ],
});

三、Rstack 生态:不止于打包器

Rspack 并不是一个孤立的打包工具,它是字节跳动 Web Infra 团队构建的统一 JavaScript 工具链 Rstack 的核心。Rstack 包含以下工具,覆盖了前端开发的全生命周期:

3.1 核心工具矩阵

工具定位核心能力
Rspack打包器Rust 驱动的高性能打包器,兼容 webpack API
Rsbuild构建工具基于 Rspack 的开箱即用构建工具,零配置启动
Rslib库开发工具基于 Rsbuild 的库开发工具,支持 ESM/CJS/UMD 输出
Rspress文档站点基于 Rsbuild 的静态站点生成器,支持 MDX
Rsdoctor构建分析AI 友好的构建分析器,可视化构建过程
Rstest测试框架基于 Rspack 的测试框架,兼容 Jest API
RslintLinter高性能 Linter,兼容 ESLint 规则

3.2 Rsbuild:零配置的构建体验

Rsbuild 是 Rstack 中最面向普通开发者的工具。它提供了开箱即用的构建配置,开发者无需了解 webpack 或 Rspack 的复杂配置就能快速启动项目。

// rsbuild.config.ts
import { defineConfig } from '@rsbuild/core';

export default defineConfig({
  // 零配置!Rsbuild 自动检测框架并应用最优配置
  source: {
    entry: {
      index: './src/index.tsx',
    },
  },
  // 开发服务器配置
  server: {
    port: 3000,
  },
});

Rsbuild 支持 React、Vue、Svelte、Solid 等主流框架,并且针对每个框架都提供了优化过的默认配置。它还集成了 CSS Modules、PostCSS、Less/Sass 等常用功能,开发者只需关注业务逻辑。

3.3 Rsdoctor:AI 友好的构建分析

Rsdoctor 是 Rstack 中一个独特的工具——它不仅是一个构建分析器,还是一个AI 友好的构建分析器。它可以输出结构化的构建诊断信息,供 AI Agent 消费和分析。

// rsdoctor.config.ts
import { RsdoctorRspackPlugin } from '@rsdoctor/rspack-plugin';

export default defineConfig({
  plugins: [
    new RsdoctorRspackPlugin({
      // 开启详细分析
      detailed: true,
      // 输出 AI 友好的诊断报告
      aiFriendly: true,
    }),
  ],
});

Rsdoctor 可以分析构建的每个阶段耗时、模块依赖图、产物大小分布、Loader/Plugin 性能瓶颈等,并生成可视化的报告。


四、从 webpack 迁移到 Rspack:实战指南

4.1 兼容性评估

Rspack 的核心优势之一是与 webpack 约 95% 的配置兼容。这意味着大多数 webpack 项目可以以极低的成本迁移到 Rspack。

Rspack 支持的 webpack 特性包括:

  • Loader 生态:几乎所有的 webpack loader 都可以在 Rspack 中使用
  • Plugin 生态:大部分 webpack 插件经过小幅修改即可兼容
  • 配置格式:webpack 的配置格式在 Rspack 中基本通用
  • Module Federation:完整支持 Module Federation 2.0

4.2 迁移步骤

Step 1:安装 Rspack

# 替换 webpack 相关依赖
npm uninstall webpack webpack-cli webpack-dev-server
npm install @rspack/core @rspack/cli @rspack/dev-server -D

Step 2:修改配置文件

// webpack.config.js (迁移前)
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    path: __dirname + '/dist',
    filename: 'bundle.[contenthash].js',
  },
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        use: 'babel-loader', // 或替换为内置 SWC
        exclude: /node_modules/,
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({ template: './src/index.html' }),
  ],
  devServer: {
    port: 3000,
    hot: true,
  },
};
// rspack.config.ts (迁移后)
import path from 'node:path';
import { defineConfig } from '@rspack/core';
import HtmlWebpackPlugin from 'html-webpack-plugin';

export default defineConfig({
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.[contenthash].js',
  },
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        // Rspack 内置 SWC loader,性能更好
        type: 'javascript/auto',
        parser: {
          // 使用内置 SWC 处理 JSX
        },
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({ template: './src/index.html' }),
  ],
  devServer: {
    port: 3000,
    hot: true,
  },
});

Step 3:使用内置 SWC Loader(可选但推荐)

// 使用内置 SWC 替代 babel-loader
// 性能提升 20-70 倍
{
  test: /\.jsx?$/,
  type: 'javascript/auto',
  parser: {
    // Rspack 2.0 会自动检测语法并应用正确的转译配置
  },
}

Step 4:开启持久化缓存

export default defineConfig({
  cache: {
    type: 'filesystem',
    // 首次构建后,后续构建将大幅加速
  },
});

4.3 常见问题与解决方案

Q:某些 webpack 插件不兼容怎么办?

A:Rspack 提供了兼容层来处理大部分差异。对于少数不兼容的插件,可以查看 Rspack 的插件兼容性文档,通常只需要小幅修改。

Q:Module Federation 的共享依赖怎么处理?

A:Rspack 2.0 完整支持 Module Federation 2.0,并且新增了共享依赖的 Tree Shaking 能力。迁移时需要将 @module-federation/enhanced 替换为 Rspack 内置的 Module Federation 支持。

Q:如何验证迁移后的构建产物是否一致?

A:建议使用 Rsdoctor 对比迁移前后的构建产物,分析模块大小、代码分割策略、Tree Shaking 结果等是否符合预期。


五、竞争格局:Rspack vs Vite vs Turbopack

5.1 架构哲学对比

维度RspackViteTurbopack
核心语言Rust + TypeScriptGo (esbuild) + Rust (Rolldown)Rust
设计理念webpack 兼容,渐进迁移原生 ESM,开发优先Turborepo 继承者,增量计算
webpack 兼容性95%+ 配置兼容需要重写配置不兼容
生态成熟度高(复用 webpack 生态)高(自有生态)中(仍在发展)
生产构建Rust 并行打包Rolldown (Rust)增量计算

5.2 性能对比

根据 build-tools-performance 基准测试(1000 个 React 组件):

工具Dev 启动(无缓存)Dev 启动(有缓存)HMR内存占用
Rspack CLI 2.1.41097ms783ms148ms366MB
Rsbuild 2.1.61116ms943ms233ms322MB
Vite 8.x~2s~1.5s130ms~300MB
webpack 5.x21.4s~15s2.78s~600MB

Rspack 在开发启动速度上领先,Vite 在 HMR 速度上略占优势,webpack 在两者面前都显得力不从心。

5.3 选型建议

  • 已有 webpack 项目,追求迁移成本最低 → Rspack(配置 95% 兼容)
  • 全新项目,追求极致开发体验 → Rsbuild(零配置)或 Vite
  • 大型 monorepo,需要增量构建 → Rspack + Turborepo
  • 库开发,需要多格式输出 → Rslib

六、实战:用 Rspack 构建一个生产级 React 应用

6.1 项目初始化

# 使用 Rsbuild 快速初始化
npm create rsbuild@latest my-app -- --template react
cd my-app
npm install
npm run dev

6.2 自定义 Rspack 配置

// rspack.config.ts
import path from 'node:path';
import { defineConfig, type Configuration } from '@rspack/core';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import CssMinimizerPlugin from 'css-minimizer-webpack-plugin';

export default defineConfig({
  mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
  entry: './src/index.tsx',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'js/[name].[contenthash:8].js',
    chunkFilename: 'js/[name].[contenthash:8].chunk.js',
    clean: true,
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.jsx', '.js', '.json'],
    alias: {
      '@': path.resolve(__dirname, 'src'),
    },
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        exclude: /node_modules/,
        // 使用内置 SWC loader
        type: 'javascript/auto',
      },
      {
        test: /\.css$/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              modules: {
                auto: true,
                localIdentName: '[name]__[local]--[hash:base64:5]',
              },
            },
          },
        ],
      },
      {
        test: /\.(png|jpe?g|gif|svg)$/i,
        type: 'asset/resource',
        generator: {
          filename: 'images/[name].[hash:8][ext]',
        },
      },
    ],
  },
  optimization: {
    minimizer: [
      '...',  // 继承默认的 SWC Minimizer
      new CssMinimizerPlugin(),
    ],
    splitChunks: {
      chunks: 'all',
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          priority: 10,
        },
        common: {
          minChunks: 2,
          priority: 5,
          reuseExistingChunk: true,
        },
      },
    },
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './public/index.html',
      minify: {
        removeComments: true,
        collapseWhitespace: true,
      },
    }),
  ],
  cache: {
    type: 'filesystem',
  },
  devServer: {
    port: 3000,
    hot: true,
    historyApiFallback: true,
    proxy: {
      '/api': {
        target: 'http://localhost:8080',
        changeOrigin: true,
      },
    },
  },
} satisfies Configuration);

6.3 性能监控

使用 Rsdoctor 监控构建性能:

// rspack.config.ts(开发环境追加)
import { RsdoctorRspackPlugin } from '@rsdoctor/rspack-plugin';

const config = {
  // ... 其他配置
  plugins: [
    // ... 其他插件
    process.env.RSDOCTOR && new RsdoctorRspackPlugin({
      mode: 'normal',
      // 生成构建分析报告
    }),
  ].filter(Boolean),
};

运行构建时设置环境变量即可生成分析报告:

RSDOCTOR=true rspack build

七、Rspack 的未来:从打包器到工具链

7.1 路线图展望

根据 Rspack 团队公布的路线图,未来的发展方向包括:

  1. React Server Components 的正式支持:Rspack 2.0 已经引入了实验性的 RSC 支持,未来将成为一等公民
  2. Rust 原生的 CSS 处理:通过 Lightning CSS 深度集成,实现 CSS 编译、压缩、兼容性处理的全链路 Rust 化
  3. 更智能的代码分割:基于运行时使用数据的自适应代码分割策略
  4. WebAssembly 构建支持:原生支持 WASM 模块的构建和优化

7.2 对前端生态的影响

Rspack 2.0 的发布标志着一个重要的行业趋势:前端工具链正在从 JavaScript 向 Rust 迁移。这不是简单的语言替换,而是整个开发范式的转变:

  • 构建速度不再是瓶颈:10000 组件的项目在 1.4 秒内完成生产构建,开发者可以频繁执行完整的生产构建来验证优化效果
  • 供应链安全得到重视:192 个依赖砍到 1 个,不是炫技,而是对供应链安全的严肃态度
  • webpack 生态的延续而非终结:Rspack 证明了「在不破坏现有生态的前提下实现性能飞跃」是可能的

7.3 给开发者的建议

  1. 新项目可以直接使用 Rspack:通过 Rsbuild 零配置启动,或直接使用 Rspack 的 webpack 兼容配置
  2. 现有 webpack 项目可以渐进迁移:Rspack 的 95% 配置兼容性意味着迁移成本极低
  3. 关注 Rstack 生态:Rsbuild、Rslib、Rstest 等工具正在形成完整的开发体验闭环
  4. 拥抱 Rust 工具链:SWC、Lightning CSS、Biome 等 Rust 工具正在重塑前端开发体验

总结

Rspack 2.0 不只是一个更快的打包器,它是字节跳动 Web Infra 团队对「前端工具链应该是什么样」这个问题的回答。通过 Rust 的极致性能、webpack 的兼容性哲学、以及从 192 到 1 的供应链安全态度,Rspack 2.0 为前端构建工具树立了一个新的标杆。

在 Vite、Turbopack、Rolldown 等竞品的包围下,Rspack 选择了一条独特的路径:不做革命者,做进化者。这种务实的哲学,或许正是它能在激烈的竞争中脱颖而出的关键。

如果你正在被 webpack 的构建速度折磨,或者正在犹豫是否要从 webpack 迁移到 Vite,不妨试试 Rspack——它可能就是你一直在寻找的那个「两全其美」的方案。


参考资源

推荐文章

Gin 框架的中间件 代码压缩
2024-11-19 08:23:48 +0800 CST
mysql 计算附近的人
2024-11-18 13:51:11 +0800 CST
在 Rust 中使用 OpenCV 进行绘图
2024-11-19 06:58:07 +0800 CST
程序员茄子在线接单