React Compiler 实验性功能介绍

原文信息: 查看原文查看原文

React Compiler

- React

本文将为您介绍新的实验性 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 能够深入理解您的代码。这使得它能够为您的代码添加自动优化。

您可能熟悉通过 useMemouseCallbackReact.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 ✨”标志。

分享于 2024-05-17

访问量 54

预览图片