← 文章 / 编程开发
Hacker News 22小时前 · 2026-09-05 21:24:08 · 8 阅读

Rust React Compiler 现已原生支持 Vite

2026 年 8 月 4 日,oxc 团队发布了对 Rust React Compiler 的官方支持。随后我们把拥有 1,036 个文件的 React Router 代码库(Outlyne,一个网站搭建工具)迁移了过去,构建中编译部分的耗时直接快了约 17.6 倍。

@vitejs/plugin-reactv6.1.0 版本带来了“实验性的原生 React Compiler 支持”,只需在 Vite 配置中给插件传入 { compiler: true } 即可启用。如果你无法使用 Vite React 插件(比如像我们一样在框架模式下使用 React Router),@acusti/vite-plugin-react-compiler 是一个极简的 Vite 插件,无论你的构建管线是什么样,都能对代码库执行 React 编译。

构建更快 = 开发者更爽 + CI 更省钱

这次变更最大的亮点就是速度。oxc 项目负责人 Boshen 表示

在初步基准测试中,它比 Babel 快十倍以上。

我们实测提速超过 17 倍:同样 1,036 个文件,Babel 编译要 14.3 秒,原生版本只需 0.81 秒(还是单线程)。这对我们意义重大——在 AI 辅助开发的快速迭代节奏下,CI 用量和 GitHub Actions 的时长已经是一笔实实在在的开销,而且等 CI 本身就很煎熬,还会给本就疲于奔命的注意力雪上加霜。

需要注意的是,这些提速只体现在构建流程的编译环节。构建过程中通常还有很多其他步骤,所以整体构建时间的改善不会有这么夸张。以我们为例,整体构建快了约 2.4 倍(22.1 秒 → 9.3 秒)。

那 React Compiler 的局限性呢?

虽然速度是首要亮点,但我更兴奋的是能使用最新最牛的 React Compiler 版本所带来的好处。该版本已修复了基于 Babel 的 React Compiler 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>;
}Code language: JavaScript (javascript)

之前会被跳过,现在完全支持。第三个在 Babel 编译器中会导致 bailouts(编译回退)但现在得到支持的常见模式是计算的对象属性键,例如:

import { clsx } from "clsx";

export default function Header({ itemCount }: { itemCount: number }) {
  return (
    <header className={clsx({ [`items-${itemCount}`]: itemCount > 0 })}>
      {/* ... */}
    </header>
  );
}Code language: JavaScript (javascript)

这些修复意味着在新版本中,我们应用的编译器兼容性又扩展了七个函数:其中五个得益于 try/catch 的改进,另外两个得益于计算的对象属性键。要明确的是,它支持的范围仍有局限性。我遇到的仍会导致编译器跳过组件/hook 的模式有两个:一是从 try 块内部抛出 throw,二是逻辑赋值运算符(??=&&=||=)。但使用 Rust 编译器的好处是,当这些修复落地时你会自动获得。如果你困在已停滞的 Babel 编译器上就没这么幸运了。

工具链一致性意味着没有覆盖盲区

我 excited 切换构建的最后一个原因是,我的完整工具链现在都在使用相同版本的 React Compiler,并且功能支持等效。在构建中采用 Oxlint 的 React Compiler 支持时,我仍在使用早期版本的 React Compiler。我之前描述过基于解构组件 prop bail out 的问题,并在 oxc 中提交了一个 错误 issue,因为组件在构建中没有被优化,也没有触发 lint 错误,我以为 lint 和编译器输出之间存在 disconnect。事实证明问题是 Oxlint 使用的是 oxc-transform-react v0.145.0,它支持该模式,而我在测试时使用的是同包的 v0.144.0。

现在,linter 和构建使用的是完全相同的 React Compiler,具有相同的改进和限制,因此我们无需担心未编译的组件混入生产构建。

如何使用

使用 @vitejs/plugin-react

只要你在 Vite v8+ 上,将现有的 React Vite 构建切换到原生 React Compiler,实际上只需要简化配置。当前基于 Babel 的 react.dev 说明 指定运行:

npm install -D @rolldown/plugin-babelCode language: Bash (bash)

并搭配以下 Vite 配置:

// 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()] })],
});Code language: JavaScript (javascript)

切换到原生意味着去除一些配置冗余。你只需运行:

npm install -D oxc-transform-react

并简化 Vite 配置:

// vite.config.js
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
  plugins: [react({ compiler: true })],
});Code language: JavaScript (javascript)

这还意味着你可以从 package.json 的 dev dependencies 中移除 @rolldown/plugin-babel

不使用 @vitejs/plugin-react(例如 React Router Framework Mode)

对于使用 React Router 框架模式的项目,切换方式稍有不同。React Router 有自己的 Vite 插件,需要替代 Vite React 插件来使用。之前你需要安装:

npm install -D vite-plugin-babel babel-plugin-react-compiler @babel/preset-typescriptCode language: Bash (bash)

并编写如下 Vite 配置:

// 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?$/,
    }),
  ],
});Code language: JavaScript (javascript)

现在你可以彻底移除 vite-plugin-babelbabel-plugin-react-compiler@babel/preset-typescript,只需安装:

npm install -D @acusti/vite-plugin-react-compilerCode language: Bash (bash)

然后把配置简化为:

// 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()],
  // or, if you need to pass custom compiler config:
  // reactCompiler({ compiler: { /* your existing ReactCompilerConfig */ } })
});Code language: JavaScript (javascript)

更简单、更快速、也更强大,值得庆祝。我正好知道该喝哪杯酒了。

原始来源: Hacker News

评论 (0)