React Compiler 教程文档

来源网址: https://react.dev/learn/react-compiler

建设中

这些文档仍在制作中。更多文档可以在 React Compiler 工作组仓库 找到,并会在稳定下来后整合到这些文档中。

您将学习

  • React Compiler 入门
  • 如何安装 React Compiler 和 eslint 插件
  • 故障排除

注意

React Compiler 是我们开源的一个新开源工具,以获得社区的早期反馈。它仍然有一些不足之处,还没有完全适用于生产环境。
React Compiler 依赖于 React 19 Beta。

React Compiler 仅是一个构建时工具,可以自动优化您的 React 应用。它支持纯 JavaScript,且理解 React 规则,因此不需要重新编写代码。

此外,它还包括一个 eslint 插件,这个插件会将来自 React Compiler 的分析直接显示在您的编辑器中。使您暂时没有在应用程序中使用此工具,该插件也完全可以独立运行。我们建议所有 React 开发者使用此 eslint 插件来帮助提高代码质量。

React Compiler 能做什么?

React Compiler 通过理解纯 JavaScript 语义和 React 规则深入地理解您的代码。这使它能够自动优化您的代码。

您可能现在已经熟悉如何通过手动方式记忆化,例如使用 useMemouseCallback,以及 React.memo。如果您的代码遵循 React 规则,React Compiler 可以自动为您完成这些操作。如果检测到违反规则的地方,它会自动跳过这些组件或 hooks,并继续安全编译其他代码。

如果您的代码库已经很好的记忆化了,您可能不会期望看到 React Compiler 带来明显的性能改进。实际上,要正确做到准确记忆化代码中导致性能问题的部分依赖,确实非常具有挑战性。

我应该尝试使用 React Compiler 吗?[](#should-i-try-out-the-compiler "我应该尝试使用 React Compiler 吗链接请注意,React Compiler 仍然是试验性且有许多不足之处。虽然它已被 Meta 等公司投入生产使用,但将它投入生产环境还需保证您代码中良好遵循了 React 规则

您不必急于使用 React Compiler。在采用它之前,可以等到其到达稳定版本。
但是,我们仍希望您可以在应用中进行小规模试验,以便将您的反馈 提供给我们,帮助改进 React Compiler。

入门

除了这些文档,我们推荐您查看 React Compiler 工作组 以获取更多有关 React Compiler 的信息和讨论。

在代码库中部署 React Compiler

现有项目

React Compiler 旨在编译遵循 React 规则 的函数式组件和 hooks。它可以跳过(取消)这些组件或 hooks 来处理违反这些规则的代码。然而,由于 JavaScript 的灵活性,React Compiler可能捕获所有可能的违规行为,并可能出现假阳性情况而进行编译:这意味着, 它可能会意外编译违反 React 规则的组件或 hook,这可能导致未定义行为。

因此,要成功在现有项目中引入 React Compiler,我们建议首先在一个较小的代码目录上运行它。可以通过将 React Compiler 配置为仅运行在特定目录实现:

const ReactCompilerConfig = {
  sources: (filename) => {
    return filename.indexOf('src/path/to/dir') !== -1;
  },
};

在少数情况下,您还可以使用 compilationMode: "annotation" 选项,将此工具配置为“选择加入”模式。这样它将仅编译带有 "use memo" 指令的组件和 hooks。请注意,annotation 模式是暂时的,是为了帮助早期采用者,我们不打算长期使用 "use memo" 指令。

const ReactCompilerConfig = {
  compilationMode: "annotation",
};

// src/app.jsx
export default function App() {
  "use memo";
  // ...
}

当您对部署 React Compiler 更加自信时,可以扩大覆盖范围到其他目录或整个应用程序。

如果您正在开始一个新项目,可以在整个代码库启用 React Compiler,这是默认行为。

安装

检查兼容性

在安装 React Compiler 之前,你可以先检查代码库是否兼容:

npx react-compiler-healthcheck

这个脚本会:

  • 检查有多少组件可以成功优化:越高越好
  • 检查 <StrictMode> 使用情况:启用并遵循它意味着更可能遵循 React 规则
  • 检查不兼容库的使用情况:已知与 React Compiler 不兼容的库

作为示例:

成功编译了 9 个组件中的 8 个。未发现使用 StrictMode。没有发现使用任何不兼容库。

安装 eslint-plugin-react-compiler

React Compiler 也为 eslint 提供支持。eslint 插件可以 独立 于 React Compiler 使用,这意味着即使在应用程序中没有使用它,也可以独立使用 eslint 插件。

npm install eslint-plugin-react-compiler

然后,将其添加 eslint 配置中:

module.exports = {
  plugins: ['eslint-plugin-react-compiler'],
  rules: {
    'react-compiler/react-compiler': "error",
  },
};

使用 Babel

npm install babel-plugin-react-compiler

React Compiler 包含一个 Babel 插件,它可以插入到您的构建流水线中。

安装后,将其添加到 Babel 配置中。请注意,React Compiler 必须 第一个运行在流水线中:

// babel.config.js
const ReactCompilerConfig = { /* ... */ };
module.exports = function() {
  return {
    plugins: [[
      'babel-plugin-react-compiler', 
      ReactCompilerConfig
    ]] // 必须首先运行!
    // ...
     };
};

babel-plugin-react-compiler 应在其他 Babel 插件之前运行,因为 React Compiler 需要源代码信息准确分析代码。

在 Vite 中使用

如果您使用 Vite,可以将该插件添加到 vite-plugin:

// vite.config.js
const ReactCompilerConfig = { /* ... */ };
export default defineConfig(() => {
  return {
    plugins: [react({
      babel: {
        plugins: [[
          "babel-plugin-react-compiler", 
          ReactCompilerConfig
        ]]
      }
    })]
    // ...
  };
});

在 Next.js 中使用

Next.js 支持通过 Babel 进行较慢的流水线。您可以通过 配置 Babel 来添加 babel.config.js 文件以启用它。

在 Remix 中使用

安装 vite-plugin-babel,并将 React Compiler 的 Babel 插件添加到其中:

npm install vite-plugin-babel
// vite.config.js
import babel from "vite-plugin-babel";
const ReactCompilerConfig = { /* ... */ };
export default defineConfig({
  plugins: [
    remix({ /* ... */ }),
    babel({
      filter: /\.[jt]sx?$/,
      babelConfig: {
        presets: ["@babel/preset-typescript"], // 如果使用 TypeScript 调试 preset
        plugins [[
          "babel-plugin-react-compiler", 
          ReactCompilerConfig
        ]],
      }
    })
  ]
});

在 Webpack 中集成

您可以为 React Compiler 创建您自己的 loader,如下示:

const ReactCompilerConfig = { /* ... */ };
const BabelPluginReactCompiler = require('babel-plugin-react-compiler');

function reactCompilerLoader(sourceCode, sourceMap) {
  // ...
  const result = transformSync(sourceCode, {
    // ...
    plugins: [[
      BabelPluginReactCompiler, 
      ReactCompilerConfig
    ]],
    // ...
  });

  if (result === null) {
    this.callback(Error(`转换"${options.filename}"失败`));
    return;
  }

  this.callback(null,
    result.code,
    result.map === null ? undefined : result.map
  );
}

module.exports = reactCompilerLoader;

在 Expo 集成

Expo 通过 Metro 使用 Babel,因此要获取安装代理,请参阅 Babel 使用指南

在 React Native (Metro) 集成

React Native 通过 Metro 使用 Babel,因此请参阅 使用 Babel 部分获取安装说明。

故障排除

报告问题

请首先在 React Compiler Playground 创建最小复现程序,并将其包含在您的错误报告中。

您在 facebook/react repo 提交问题。

您还可以申请成为 React Compiler 工作组成员来反馈意见,详见 README 获取更多加入详情。

常见问题

(0 , _c) is not a function 错误

当您没有使用 React 19 Beta 及以上时,在 JavaScript 模块评估期间会发生此问题。要解决此问题,请首先 将您的应用升级至 React 19 Beta

调试

检查组件是否已经过优化

React DevTools

React Devtools (v5.0+) 内置支持 React,并将在由 React Compiler 优化的组件旁边显示“Memo ✨”徽章。

其他问题

请查看https://github.com/reactwg/react-compiler/discussions/7 行了解更多。