Rspack / Rsbuild Rust 系的崛起
Rspack / Rsbuild Rust 系的崛起
写在前面
上一篇讲了 Vite 的双引擎设计。本篇讲 Rspack——字节跳动开源的 Rust 写的 webpack 兼容方案,以及它的封装 Rsbuild。Rspack 解决了 Vite 解决不了的问题:存量 webpack 项目的无痛迁移。
一、为什么需要 Rspack
1.1 字节的痛点
字节跳动内部有几千个 webpack 项目,每个项目都要等 30 秒冷启动、5 秒 HMR。
他们试过:
- 用 Vite 替代 webpack:生态不兼容,几十个自定义 webpack loader/plugin 用不了
- 用 esbuild:API 太底层,要从零重写所有项目
- 用 swc 替代 babel-loader:能提速 5x,但还是 webpack,冷启动还是慢
需要一个既能保留 webpack 配置,又能跑得和 Vite 一样快的方案。
1.2 Rspack 的目标
和 webpack 100% 配置兼容,但用 Rust 重写核心,速度提升 5-10 倍。
二、Rspack 的架构
2.1 核心组件
┌─────────────────────────────────────┐
│ Rspack (Rust) │
│ ├─ Compiler (Rust) │ ← 核心编译逻辑
│ ├─ Module Federation (Rust) │ ← 内置模块联邦
│ ├─ SWC Transform (Rust) │ ← TS/JSX 转译
│ ├─ Loader Runner (Rust+JS) │ ← 运行 JS loader
│ └─ Plugin System │ ← 兼容 webpack 插件
└─────────────────────────────────────┘
2.2 关键模块
Rust 核心
// Rspack 的 Rust 代码示意
pub struct Compiler {
pub options: CompilerOptions,
pub plugins: Vec<Box<dyn Plugin>>,
pub resolvers: HashMap<ResolverKind, Resolver>,
}
impl Compiler {
pub fn run(&mut self) -> Result<()> {
// 1. 解析入口
// 2. 并行处理所有模块
// 3. 构建依赖图
// 4. 优化 chunk
// 5. 输出文件
}
}
用 Rayon 做并行处理,多核 CPU 充分利用。
SWC 转译
Rspack 用 swc(也是 Rust 写的)做 TS/JSX 转译,比 Babel 快 5-20 倍。
// 用 swc 转译 TS
let fm = swc::SourceFile::new(...);
let lexer = Lexer::new(...);
let mut parser = Parser::new_from(lexer);
let module = parser.parse_module().unwrap();
let transformed = Transform::new().transform(module);
Loader Runner
Rspack 用 Rust 调用 JS loader(兼容 webpack loader):
// Rust 调用 JS loader
let result = node_runtime.call(
loader_path,
source_code,
loader_options,
)?;
大部分 webpack loader 可以直接用,但调用开销比 webpack 小(Rust 直接处理)。
2.3 性能对比
字节官方 benchmark:
| 项目 | webpack 5 | Rspack | 提升 |
|---|---|---|---|
| Modern.js(中等) | 12.5s | 1.8s | 7x |
| ant-design-pro(大型) | 28s | 4.2s | 6.7x |
| Next.js 13(超大) | 65s | 9.8s | 6.6x |
典型提升 5-10 倍。
三、Rspack 的使用
3.1 配置文件
// rspack.config.js
module.exports = {
entry: './src/index.js',
output: {
path: __dirname + '/dist',
filename: '[name].[contenthash].js',
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'builtin:swc-loader',
options: {
jsc: {
parser: { syntax: 'typescript', tsx: true },
target: 'es2020',
},
},
},
{
test: /\.css$/,
use: ['css-loader', 'postcss-loader'],
},
],
},
plugins: [
new rspack.HtmlRspackPlugin({ // 替代 HtmlWebpackPlugin
template: './public/index.html',
}),
],
};
几乎和 webpack 一模一样,只是部分内置 loader/plugin 用 builtin: 前缀。
3.2 启动
# 安装
npm install -D @rspack/core @rspack/cli
# 启动 dev server
npx rspack serve
# 构建
npx rspack build
四、Rsbuild:Rspack 的封装
4.1 Rsbuild 是什么
Rsbuild 是字节在 Rspack 之上的封装——提供开箱即用的开发体验。
// rsbuild.config.ts
import { defineConfig } from '@rsbuild/core';
import { pluginReact } from '@rsbuild/plugin-react';
export default defineConfig({
plugins: [pluginReact()],
html: {
template: './index.html',
},
source: {
entry: { index: './src/index.ts' },
},
});
4.2 Rsbuild 内置能力
| 能力 | 默认支持 |
|---|---|
| TypeScript | ✅(swc 转译) |
| JSX | ✅ |
| CSS / Sass / Less | ✅ |
| CSS Modules | ✅ |
| PostCSS(autoprefixer) | ✅ |
| 图片 / 字体 / SVG | ✅ |
| HTML 处理 | ✅ |
| 静态资源处理 | ✅ |
| 代码分割 | ✅ |
| Tree Shaking | ✅ |
| Source Map | ✅ |
| HMR | ✅ |
| TypeScript 类型检查(独立) | ⚙️(可选插件) |
对比 webpack:这些都需要手动配置 loader/plugin。
4.3 Rsbuild 的命令
# 开发
npx rsbuild dev
# 构建
npx rsbuild build
# 预览构建产物
npx rsbuild preview
4.4 Rsbuild 生态
字节围绕 Rsbuild 建了一整套工具:
- Rsbuild:构建工具
- Rspress:静态站点生成(类似 VitePress)
- Rslib:库打包工具
- Modern.js:现代 Web 应用框架(字节主推)
五、webpack 兼容性实测
5.1 Loader 兼容性
| Loader | 兼容情况 |
|---|---|
babel-loader |
✅ 完全兼容 |
css-loader / style-loader |
✅ 完全兼容 |
postcss-loader |
✅ 完全兼容 |
sass-loader / less-loader |
✅ 完全兼容 |
file-loader / url-loader |
⚙️ Rspack 有内置,无需 loader |
ts-loader |
⚙️ 用 swc-loader 替代,更快 |
vue-loader |
⚙️ 需要 vue-loader 16+ |
| 自定义 loader | ✅ 99% 兼容 |
5.2 Plugin 兼容性
| Plugin | 兼容情况 |
|---|---|
HtmlWebpackPlugin |
⚙️ 用 HtmlRspackPlugin 替代 |
MiniCssExtractPlugin |
⚙️ 用 CssExtractRspackPlugin 替代 |
CopyWebpackPlugin |
✅ 兼容 |
DefinePlugin |
✅ 完全兼容 |
ProvidePlugin |
✅ 完全兼容 |
webpack-bundle-analyzer |
⚙️ 用 Rsbuild 的 bundle-analyzer |
| 自定义 plugin | ⚠️ 大部分兼容 |
5.3 配置兼容性
// webpack.config.js 改几个名字就能用
const config = {
entry: './src/index.js',
output: { path: './dist', filename: '[name].js' },
module: {
rules: [{ test: /\.css$/, use: 'css-loader' }],
},
// ... 其他都一样
};
module.exports = config;
90% 的 webpack 项目可以直接跑 Rspack。
5.4 真实迁移案例
公司项目 from-webpack-to-rspack:
- const path = require('path');
- const HtmlWebpackPlugin = require('html-webpack-plugin');
- const MiniCssExtractPlugin = require('mini-css-extract-plugin');
- const { DefinePlugin } = require('webpack');
+ const path = require('path');
+ const rspack = require('@rspack/core');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash:8].js',
clean: true,
},
module: {
rules: [
- { test: /\.tsx?$/, use: 'ts-loader' },
+ { test: /\.tsx?$/, loader: 'builtin:swc-loader' },
{
test: /\.css$/,
- use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader'],
+ use: [rspack.CssExtractRspackPlugin.loader, 'css-loader', 'postcss-loader'],
},
],
},
plugins: [
- new HtmlWebpackPlugin({ template: './public/index.html' }),
+ new rspack.HtmlRspackPlugin({ template: './public/index.html' }),
- new MiniCssExtractPlugin({ filename: '[name].[contenthash:8].css' }),
+ new rspack.CssExtractRspackPlugin({ filename: '[name].[contenthash:8].css' }),
new rspack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production'),
}),
],
};
改动 < 50 行,迁移后冷启动从 60 秒降到 8 秒。
六、Rspack 的优势场景
6.1 存量 webpack 迁移
这是 Rspack 最大的优势——大部分公司都有存量 webpack 项目。
迁移成本: < 1 周(主要是改 plugin)
性能提升: 5-10 倍
6.2 大型 monorepo
字节内部的 monorepo 用 Rspack + Turborepo 远程缓存,构建时间从 30 分钟降到 5 分钟。
6.3 自定义 loader 多
webpack 的 JS loader 灵活,Rspack 完全兼容——很多公司有自定义 loader,Rspack 不用重写。
七、Rspack 的局限
7.1 还在快速发展
- 文档不如 webpack 完整
- 某些边界情况有 bug
- 生态还在追赶
7.2 生产构建产物偶尔有差异
webpack 5.x 的某些 advanced optimization,Rspack 还在追赶。
7.3 swc-loader 不能完全替代 babel-loader
某些特殊 babel 插件(自定义语法),swc-loader 不支持。
八、Rspack vs Vite vs Turbopack
8.1 对比表
| 维度 | Rspack | Vite | Turbopack |
|---|---|---|---|
| 配置兼容 webpack | ✅ | ❌ | ❌ |
| 开发体验 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| 生产产物 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| 启动速度 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 框架绑定 | 无 | 无 | Next.js |
| 生态 | 早期 | 成熟 | 早期 |
8.2 选型建议
存量 webpack → Rspack / Rsbuild(无痛迁移)
新项目+体验优先 → Vite
Next.js 项目 → Turbopack(默认)
存量 Vite → 继续用 Vite
九、Rsbuild 实战案例
9.1 项目结构
.
├── rsbuild.config.ts
├── src/
│ ├── index.ts
│ ├── App.tsx
│ └── components/
├── public/
└── tsconfig.json
9.2 完整配置
// rsbuild.config.ts
import { defineConfig } from '@rsbuild/core';
import { pluginReact } from '@rsbuild/plugin-react';
import { pluginTypeCheck } from '@rsbuild/plugin-type-check';
export default defineConfig({
plugins: [
pluginReact(),
pluginTypeCheck(), // 独立类型检查
],
source: {
entry: {
index: './src/index.tsx',
},
alias: {
'@': './src',
},
define: {
'process.env.APP_VERSION': JSON.stringify(process.env.npm_package_version),
},
},
html: {
template: './public/index.html',
title: 'My App',
meta: {
description: 'My React App',
},
},
output: {
distPath: {
root: 'dist',
},
polyfill: 'usage', // 按需 polyfill
cleanDistPath: true,
},
server: {
port: 3000,
open: true,
historyApiFallback: true,
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
},
},
},
performance: {
chunkSplit: {
strategy: 'split-by-experience',
},
removeConsole: ['log', 'info'], // 生产环境去掉 console
},
tools: {
swc: {
jsc: {
transform: {
react: {
runtime: 'automatic', // React 17+ JSX runtime
},
},
},
},
},
});
9.3 性能对比
| 指标 | webpack 5 | Rsbuild | 提升 |
|---|---|---|---|
| 冷启动 | 45s | 6s | 7.5x |
| HMR | 5s | 300ms | 16x |
| 生产构建 | 60s | 18s | 3.3x |
| 内存占用 | 3.5GB | 1.8GB | 1.9x |
十、Module Federation 2.0
Rspack 把 Module Federation 做到了生产可用:
// 应用 A - 暴露组件
new rspack.container.ModuleFederationPlugin({
name: 'appA',
filename: 'remoteEntry.js',
exposes: {
'./Button': './src/components/Button',
'./Modal': './src/components/Modal',
},
shared: {
react: { singleton: true },
'react-dom': { singleton: true },
},
});
// 应用 B - 消费组件
new rspack.container.ModuleFederationPlugin({
name: 'appB',
remotes: {
appA: 'appA@https://cdn.company.com/appA/remoteEntry.js',
},
shared: {
react: { singleton: true },
},
});
字节内部大量微前端都用 MF——Rspack 让 MF 真正可用了。
十一、本篇小结
| 主题 | 关键点 |
|---|---|
| Rspack | Rust 写的 webpack 兼容方案 |
| Rsbuild | Rspack 之上的开箱即用封装 |
| 性能 | 比 webpack 5-10 倍 |
| 兼容性 | 90% webpack 项目可直接迁移 |
| 适用 | 存量 webpack 项目 |
| 关键决策 | 推荐 |
|---|---|
| 存量 webpack | Rspack |
| 新项目 | Vite / Rsbuild |
| 库代码 | Rollup |
下一篇讲 从 webpack 迁移到 Rspack 实战——rsbuild 那篇文章的完整展开。