Rust 版 React Compiler 正式原生集成进 Vite
译注:本文编译自 Master.dev 博客文章《React Now Rusted All The Way Out》,原文发布于 2026 年 9 月 4 日,作者 Andrew Patton。原文链接见文末。文章记录了作者将 1,036 个文件的 React Router 代码库迁移到 Rust 版 React Compiler 的实测数据与经验。
在 oxc 团队于 2026 年 8 月 4 日发布对 Rust 版 React Compiler 的官方支持后,作者将旗下网站构建工具 Outlyne 的 1,036 个文件的 React Router 代码库切换到了该编译器,编译环节获得了约 17.6 倍的提速。
构建提速:开发者更省心,CI 更省钱
本次变更最受关注的是速度。据 oxc 项目负责人 Boshen 介绍,初步基准测试中它比 Babel 快 10 倍以上。作者实测的提速超过 17 倍:1,036 个文件从 Babel 构建时的 14.3 秒降至原生单线程的 0.81 秒。
作者指出,在 AI 辅助开发带来高频变更的背景下,CI 用量与 GitHub Actions 分钟数已成为实打实的成本项,等待 CI 也令人疲惫。不过需要说明的是,这一提速仅作用于构建流程中的编译环节,整体构建时间的改善不会如此夸张——作者的实测整体构建从 22.1 秒降至 9.3 秒,约 2.4 倍。
React Compiler 的限制修复
相比速度,作者更看重的是用上了最新版本的 React Compiler,它修复了基于 Babel 的 v1.0 版本中若干重要的 JavaScript 支持限制,包括:
- try/catch 块中的条件逻辑:这是 1.0 稳定版中困扰许多开发者的阻塞点,现已支持。
- 解构组件 prop 的重新赋值并在嵌套闭包中使用:例如:
export default function Foo({ value }: { value: null | string }) {
value = value ?? "this is a fallback";
return <button onClick={() => console.log(value)}>{value}</button>;
}此前会被跳过,现在完全支持。
- 计算属性键(computed object property keys):例如:
import { clsx } from "clsx";
export default function Header({ itemCount }: { itemCount: number }) {
return (
<header className={clsx({ [`items-${itemCount}`]: itemCount > 0 })}>
{/* ... */}
</header>
);
}这些修复让作者应用中的编译器兼容性额外覆盖了 7 个函数:5 个来自 try/catch 改进,2 个来自计算属性键。
不过仍有限制。作者遇到的两类仍会导致编译器跳过组件/钩子的模式是:在 try 块内部 throw,以及逻辑赋值运算符(??=、&&=、||=)。但使用 Rust 编译器意味着这些修复落地后即可获得,而停留在 Babel 版编译器上则无此待遇。
工具链一致,消除覆盖盲区
作者切换构建的另一个理由是:整条工具链现在使用同一版本的 React Compiler,特性支持一致。此前他在构建仍用旧版 React Compiler 时启用了 Oxlint 的 React Compiler 支持,并因前述解构 prop 的跳过问题在 oxc 提了一个错误 issue——组件在构建时未被优化,却也没有触发 lint 错误,他一度以为 lint 与编译器输出脱节。最终发现原因是 Oxlint 使用的是 oxc-transform-react v0.145.0(支持该模式),而他测试用的是同包的 v0.144.0。
如今 linter 与构建使用完全相同的 React Compiler,改进与限制一致,不必再担心未编译的组件混入生产构建。
如何使用
使用 @vitejs/plugin-react
只要使用 Vite v8+,将现有 React Vite 构建切换到原生 React Compiler 实际上就是简化配置。原先基于 Babel 的官方指引要求安装:
npm install -D @rolldown/plugin-babel配置如下:
// vite.config.js
import { defineConfig } from "vite";
import react, { reactCompilerPreset } from "@vitejs/plugin-react";
import babel from "@rolldown/plugin-babel";
export default defineConfig({
plugins: [react(), babel({ presets: [reactCompilerPreset()] })],
});改用原生后,安装:
npm install -D oxc-transform-react配置简化为:
// vite.config.js
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react({ compiler: true })],
});同时可以从 package.json 的 devDependencies 中移除 @rolldown/plugin-babel。
不使用 @vitejs/plugin-react(如 React Router 框架模式)
对于使用 React Router 框架模式的代码库,切换方式略有不同。React Router 有自己的 Vite 插件,需替代 Vite React 插件运行。原先需要安装:
npm install -D vite-plugin-babel babel-plugin-react-compiler @babel/preset-typescript配置如下:
// vite.config.js
import { defineConfig } from "vite";
import babel from "vite-plugin-babel";
import { reactRouter } from "@react-router/dev/vite";
const ReactCompilerConfig = {
/* optional config if you have it */
};
export default defineConfig({
plugins: [
reactRouter(),
babel({
babelConfig: {
presets: ["@babel/preset-typescript"], // if you use TypeScript
plugins: [["babel-plugin-react-compiler", ReactCompilerConfig]],
},
exclude: /node_modules/,
include: /\.(jt)sx?$/,
}),
],
});现在可以完全移除 vite-plugin-babel、babel-plugin-react-compiler 和 @babel/preset-typescript,改为安装:
npm install -D @acusti/vite-plugin-react-compiler配置简化为:
// vite.config.js
import { defineConfig } from "vite";
import reactCompiler from "@acusti/vite-plugin-react-compiler";
import { reactRouter } from "@react-router/dev/vite";
export default defineConfig({
plugins: [reactRouter(), reactCompiler()],
// 或需要传入自定义编译器配置时:
// reactCompiler({ compiler: { /* your existing ReactCompilerConfig */ } })
});更简单、更快、能力更强。