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.0 | 5.6s | 5.6s | 128ms |
| Rspack 1.7 | 3.6s | 2.2s | 134ms |
| Rspack 2.0 | 3.1s | 1.4s | 118ms |
作为对比,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 |
| Rslint | Linter | 高性能 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 架构哲学对比
| 维度 | Rspack | Vite | Turbopack |
|---|---|---|---|
| 核心语言 | Rust + TypeScript | Go (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.4 | 1097ms | 783ms | 148ms | 366MB |
| Rsbuild 2.1.6 | 1116ms | 943ms | 233ms | 322MB |
| Vite 8.x | ~2s | ~1.5s | 130ms | ~300MB |
| webpack 5.x | 21.4s | ~15s | 2.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 团队公布的路线图,未来的发展方向包括:
- React Server Components 的正式支持:Rspack 2.0 已经引入了实验性的 RSC 支持,未来将成为一等公民
- Rust 原生的 CSS 处理:通过 Lightning CSS 深度集成,实现 CSS 编译、压缩、兼容性处理的全链路 Rust 化
- 更智能的代码分割:基于运行时使用数据的自适应代码分割策略
- WebAssembly 构建支持:原生支持 WASM 模块的构建和优化
7.2 对前端生态的影响
Rspack 2.0 的发布标志着一个重要的行业趋势:前端工具链正在从 JavaScript 向 Rust 迁移。这不是简单的语言替换,而是整个开发范式的转变:
- 构建速度不再是瓶颈:10000 组件的项目在 1.4 秒内完成生产构建,开发者可以频繁执行完整的生产构建来验证优化效果
- 供应链安全得到重视:192 个依赖砍到 1 个,不是炫技,而是对供应链安全的严肃态度
- webpack 生态的延续而非终结:Rspack 证明了「在不破坏现有生态的前提下实现性能飞跃」是可能的
7.3 给开发者的建议
- 新项目可以直接使用 Rspack:通过 Rsbuild 零配置启动,或直接使用 Rspack 的 webpack 兼容配置
- 现有 webpack 项目可以渐进迁移:Rspack 的 95% 配置兼容性意味着迁移成本极低
- 关注 Rstack 生态:Rsbuild、Rslib、Rstest 等工具正在形成完整的开发体验闭环
- 拥抱 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——它可能就是你一直在寻找的那个「两全其美」的方案。
参考资源