本文将为您介绍新的实验性 React Compiler 以及如何成功地试用它。
正在建设中
这些文档仍在完善中。更多文档可以在 React Compiler 工作组仓库 中找到,并将在这些文档更加稳定时上载到这里。
注意
React Compiler 是一个新的实验性Compiler,我们将其开源以获得社区的早期反馈。它仍有一些粗糙的边缘,尚未完全准备好用于生产环境。
React Compiler需要 React 19 Beta。
React Compiler 是一个新的实验性Compiler,我们将其开源以获得社区的早期反馈。它仅是一个构建时工具,会自动优化您的 React 应用程序。它适用于纯 JavaScript,并且理解 React 规则,所以您不需要重写任何代码即可使用它。
该Compiler 还包括一个 eslint 插件,可以在您的编辑器中显示Compiler 的分析结果。该插件独立于Compiler 运行,即使您不在应用中使用Compiler 也可以使用这个插件。我们建议所有 React 开发者使用这个 eslint 插件,以帮助提高代码库的质量。
Compiler 能做什么?
通过对纯 JavaScript 语义和 React 规则 的理解,Compiler 能够深入理解您的代码。这使得它能够为您的代码添加自动优化。
您可能熟悉通过 useMemo
、useCallback
和 React.memo
手动进行记忆化。Compiler 可以自动为您完成这些工作,只要您的代码遵循 React 规则。如果它检测到规则的破坏,它会自动跳过这些组件或钩子,继续安全地编译其他代码。
如果您的代码库已经进行了很好的记忆化,您可能不会期望在使用Compiler 时看到重大性能提升。然而,实践中,手动正确记忆化那些导致性能问题的依赖关系是很难做到的。
我应该尝试使用Compiler 吗?
请注意,Compiler 仍然是实验性的,存在许多粗糙的边缘。尽管它已经在 Meta 等公司投入生产使用,但将Compiler 推向生产环境取决于您的代码库健康状况以及您对 React 规则 的遵循程度。
您现在不必急于使用Compiler 。可以等到它达到稳定版本后再采用。 然而,我们也欢迎您在应用中进行小规模实验,并向我们 提供反馈 以帮助改进Compiler 。
开始使用
除了这些文档,我们建议查看 React Compiler 工作组 以获取有关Compiler 的更多信息和讨论。
在代码库中逐步引入Compiler
现有项目
Compiler 设计用于编译遵循 React 规则 的函数组件和钩子。它也可以通过跳过(跳过)那些违反规则的组件或钩子来处理那些破坏规则的代码。然而,由于 JavaScript 的灵活性,Compiler 无法捕捉所有可能的违规行为,可能会出现错误负面结果:即Compiler 可能会意外编译违反 React 规则的组件/钩子,从而导致未定义的行为。
因此,为了在现有项目中成功引入Compiler ,我们建议首先在产品代码的小目录中运行它。您可以通过配置Compiler 仅在特定目录集上运行来实现这一点:
const ReactCompilerConfig = {
sources: (filename) => {
return filename.indexOf('src/path/to/dir') !== -1;
},
};
在极少数情况下,您也可以配置Compiler 以“选择性加入”模式运行,使用 compilationMode: "annotation"
选项。这意味着Compiler 将只编译带有 "use memo"
指令的组件和钩子。请注意,annotation
模式是一个临时的模式,旨在帮助早期采用者,我们不打算长期使用 "use memo"
指令。
const ReactCompilerConfig = {
compilationMode: "annotation",
};
// src/app.jsx
export default function App() {
"use memo";
// ...
}
当您对引入Compiler 更有信心时,可以将覆盖范围扩展到其他目录,并逐步将其推广到整个应用程序。
新项目
如果您正在启动一个新项目,可以在整个代码库中启用Compiler ,这是默认行为。
安装
检查兼容性
在安装Compiler 之前,您可以先检查您的代码库是否兼容:
npx react-compiler-healthcheck
此脚本将:
- 检查有多少组件可以成功优化:越多越好
- 检查
<StrictMode>
的使用:启用并遵循此模式意味着更有可能遵循 React 规则 - 检查不兼容库的使用:已知与Compiler 不兼容的库
例如:
终端:成功编译了 9 个组件中的 8 个。未找到 StrictMode 的使用。未找到不兼容库的使用。
安装 eslint-plugin-react-compiler
React Compiler 还支持一个 eslint 插件。eslint 插件可以 独立于 Compiler 使用,这意味着即使您不使用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
Compiler 包括一个 Babel 插件,您可以在构建管道中使用它来运行Compiler 。
安装后,将其添加到您的 Babel 配置中。请注意,Compiler 必须在管道中 首先 运行:
// babel.config.js
const ReactCompilerConfig = { /* ... */ };
module.exports = function () {
return {
plugins: [
['babel-plugin-react-compiler', ReactCompilerConfig], // 必须首先运行!
// ...
],
};
};
babel-plugin-react-compiler
应该在其他 Babel 插件之前运行,因为Compiler 需要输入源信息以进行可靠的分析。
与 Vite 一起使用
如果您使用 Vite,可以将插件添加到 vite-plugin-react:
// vite.config.js
const ReactCompilerConfig = { /* ... */ };
export default defineConfig(() => {
return {
plugins: [
react({
babel: {
plugins: [
["babel-plugin-react-compiler", ReactCompilerConfig],
],
},
}),
],
// ...
};
});
与 Next.js 一起使用
Next.js 允许通过 Babel 进行较慢的构建管道,可以通过添加 babel.config.js
文件 配置 Babel。
与 Remix 一起使用
安装 vite-plugin-babel
,并将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
plugins: [
["babel-plugin-react-compiler", ReactCompilerConfig],
],
},
}),
],
});
与 Webpack 一起使用
您可以创建自己的 React Compiler 加载器,如下所示:
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(
`Failed to transform "${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 仓库中打开问题。
您也可以申请成为 React Compiler 工作组的成员以提供反馈。请参阅 README 获取更多加入的详细信息。
常见问题
(0 , _c) is not a function
错误
这是在您未使用 React 19 Beta 及以上版本时 JavaScript 模块评估期间发生的。要解决此问题,请先 将您的应用升级到 React 19 Beta。
调试
检查组件是否已优化
React DevTools
React DevTools (v5.0+) 内置支持 React Compiler ,并将在Compiler 优化过的组件旁显示一个“Memo ✨”标志。