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 能够深入理解您的代码。这使得它能够为您的代码添加自动优化。

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

分享于 2024-05-17

访问量 953

预览图片