React 编译器【译】
date
May 16, 2024
slug
react-compiler
status
Published
tags
React
type
Post
URL
summary
Author
链接:<https://react.dev/learn/react-compiler>
这一页面将为您介绍新的实验性 React 编译器,以及如何成功尝试它。
施工中
这些文档仍在进行中。React 编译器工作组仓库中有更多文档,当它们更稳定时,将被集成到这些文档中。
您将学到
- 编译器入门
- 安装编译器和 eslint 插件
- 故障排除
注意
React 编译器是我们开源的一个新的实验性编译器,我们希望通过社区的早期反馈来改进它。它仍然有待完善,尚未完全准备好投入生产环境。
React 编译器需要 React 19 Beta。
React 编译器是我们开源的一个新的实验性编译器,我们希望通过社区的早期反馈来改进它。它是一个仅在构建时使用的工具,可以自动优化您的 React 应用。它可以与纯 JavaScript 一起工作,并且理解 React 的规则,因此您无需重写任何代码即可使用它。
该编译器还包括一个 eslint 插件,可以直接在您的编辑器中显示编译器的分析。该插件独立于编译器运行,即使您在应用中没有使用编译器,也可以使用该插件。我们建议所有 React 开发者使用这个 eslint 插件来帮助提高您的代码库质量。
编译器做了什么?
编译器通过其对纯 JavaScript 语义和 React 规则的理解,深入理解您的代码。这允许它向您的代码添加自动优化。
您可能已经熟悉通过 useMemo、useCallback 和 React.memo 进行手动记忆化。如果您的代码遵循 React 的规则,编译器可以自动为您执行此操作。如果它检测到规则的破坏,它将自动跳过仅那些组件或钩子,并继续安全地编译其他代码。
如果您的代码库已经很好地记忆化了,您可能不会期望通过编译器看到主要的性能改进。然而,在实践中,手动正确记忆化导致性能问题的依赖项是棘手的。
我应该尝试编译器吗?
请注意,编译器仍然是实验性的,并且有许多待完善的地方。虽然它已经在像 Meta 这样的公司中生产中使用,但将编译器推广到您应用的生产环境将取决于您的代码库的健康状况以及您对 React 规则的遵循程度。
您不必急于现在就使用编译器。等到它达到稳定版本再采用它是可以的。然而,我们确实希望您能在应用中进行小规模的实验尝试,以便为我们提供反馈,帮助我们改进编译器。
入门
除了这些文档外,我们还推荐您查看 React 编译器工作组以获取有关编译器的额外信息和讨论。
将编译器推广到您的代码库
现有项目
编译器旨在编译遵循 React 规则的函数组件和钩子。它也可以通过跳出(跳过)那些组件或钩子来处理违反这些规则的代码。然而,由于 JavaScript 的灵活性,编译器无法捕捉到每一个可能的违规行为,并且可能会以假阴性的方式编译:也就是说,编译器可能会意外地编译一个违反 React 规则的组件/钩子,这可能导致未定义的行为。
为此,在现有项目中成功采用编译器,我们建议首先在产品代码的一个小目录上运行它。您可以通过配置编译器仅在特定目录集上运行来实现:
const ReactCompilerConfig = {
sources: filename => {
在极少数情况下,您还可以配置编译器以“选择性加入”模式运行,使用 compilationMode: "annotation" 选项。这使得编译器仅编译使用“use memo”指令注释的组件和钩子。请注意,注释模式是临时的,旨在帮助早期采用者,我们不打算长期使用“use memo”指令。
const ReactCompilerConfig = {
当您对推广编译器更有信心时,也可以将覆盖范围扩展到其他目录,并逐渐将其推广到整个应用。
新项目
如果您正在开始一个新项目,您可以在您的整个代码库上启用编译器,这是默认行为。
安装
检查兼容性
在安装编译器之前,您可以首先检查您的代码库是否兼容:
npx react-compiler-healthcheck
这个脚本将:
- 检查有多少组件可以成功优化:越高越好
- 检查 <StrictMode> 使用情况:启用并遵循意味着更高的可能性遵循 React 规则
- 检查不兼容库的使用:已知与编译器不兼容的库
例如:
成功编译了 9 个组件中的 8 个。
未发现 StrictMode 使用。
未发现不兼容库的使用。
安装 eslint-plugin-react-compiler
React 编译器还支持一个 eslint 插件。该 eslint 插件可以独立于编译器使用,这意味着即使您不使用编译器,也可以使用 eslint 插件。
npm install eslint-plugin-react-compiler
然后,将其添加到您的 eslint 配置中:
module.exports = {
plugins: [
'eslint-plugin-react-compiler',
],
rules: {
'react-compiler/react-compiler': 2,
},
};
与 Babel 一起使用
npm install babel-plugin-react-compiler
编译器包括一个 Babel 插件,您可以在构建管道中使用它来运行编译器。
安装后,将其添加到您的 Babel 配置中。请注意,编译器在管道中首先运行至关重要:
// babel.config.js
const ReactCompilerConfig = /* ... */;
module.exports = function () {
return {
plugins: [
babel-plugin-react-compiler
应在其他 Babel 插件之前运行,因为编译器需要输入源信息进行声音分析。与 Vite 一起使用
如果您使用 Vite,可以将插件添加到 vite-plugin-react 中:
// vite.config.js
const ReactCompilerConfig = /* ... */;
export default defineConfig => {
return {
plugins: [
react({
babel: {
plugins: [
与 Next.js 一起使用
Next.js 允许通过 Babel 启用较慢的构建管道,可以通过通过添加一个 babel.config.js 文件来配置 Babel 来实现。
与 Remix 一起使用
安装 vite-plugin-babel,并将编译器的 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(new 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 Working Group 中提供反馈。有关加入的详细信息,请参见 README。
常见问题
`
(0 , _c) is not a function
`错误当您没有使用 React 19 Beta 及以上版本时,在 JavaScript 模块评估期间会发生此错误。要解决此问题,请先将您的应用程序升级到 React 19 Beta。
调试
检查组件是否已优化
React DevTools
React Devtools (v5.0+) 内置了对 React Compiler 的支持,并将显示一个“Memo ✨”徽章,旁边是已由编译器优化的组件。
其他问题
‣