React 编译器

了解如何在 Expo 应用中启用和使用 React Compiler。


新的 React 编译器 会自动对组件和钩子进行记忆化,以实现细粒度的响应式。这可以显著提升你的应用性能。你可以按照以下说明在应用中启用它。

🌐 The new React Compiler automatically memoizes components and hooks to enable fine-grained reactivity. This can lead to significant performance improvements in your app. You can enable it in your app by following the instructions below.

启用 React 编译器

🌐 Enabling React Compiler

1

检查你的项目 与 React 编译器的兼容性。

Terminal
npx react-compiler-healthcheck@latest

这通常会验证你的应用是否遵循 React 规则

🌐 This will generally verify if your app is following the rules of React.

2

在你的项目中安装 babel-plugin-react-compiler 和 React 编译器运行时:

🌐 Install babel-plugin-react-compiler and the React compiler runtime in your project:

Babel 在 Expo SDK 54 及更高版本中自动配置。

Terminal
npx expo install babel-plugin-react-compiler@beta
Terminal
npx expo install babel-plugin-react-compiler@beta react-compiler-runtime@beta

3

在你的应用配置文件中开启 React 编译器实验功能:

🌐 Toggle on the React Compiler experiment in your app config file:

app.json
{ "expo": { "experiments": { "reactCompiler": true } } }

启用代码检查工具

🌐 Enabling the linter

在未来,以下所有步骤都将由 Expo CLI 自动补齐。

此外,你应该使用 ESLint 插件在你的项目中持续执行 React 的规则。

🌐 Additionally, you should use the ESLint plugin to continuously enforce the rules of React in your project.

1

运行 npx expo lint 以确保 ESLint 已在你的应用中设置,然后安装适用于 React Compiler 的 ESLint 插件:

🌐 Run npx expo lint to ensure ESLint is setup in your app, then install the ESLint plugin for React Compiler:

Terminal
npx expo install eslint-plugin-react-compiler -- -D

2

更新你的 ESLint 配置 以包含该插件:

🌐 Update your ESLint configuration to include the plugin:

.eslintrc.js
// https://expo.nodejs.cn/guides/using-eslint/ const { defineConfig } = require('eslint/config'); const expoConfig = require('eslint-config-expo/flat'); const reactCompiler = require('eslint-plugin-react-compiler'); module.exports = defineConfig([ expoConfig, reactCompiler.configs.recommended, { ignores: ['dist/*'], }, ]);

逐步采用

🌐 Incremental adoption

你可以通过几种策略在你的应用中逐步采用 React 编译器:

🌐 You can incrementally adopt the React Compiler in your app using a few strategies:

1

配置 Babel 插件仅在特定文件或组件上运行。操作方法如下:

🌐 Configure the Babel plugin to only run on specific files or components. To do this:

  1. 如果你的项目没有 babel.config.js,可以通过运行 npx expo customize babel.config.js 来创建一个。
  2. 将以下配置添加到 babel.config.js 中:
babel.config.js
module.exports = function (api) { api.cache(true); return { presets: [ [ 'babel-preset-expo', { 'react-compiler': { sources: filename => { // Match file names to include in the React Compiler. return filename.includes('src/path/to/dir'); }, }, }, ], ], }; };

每当你更改 babel.config.js 文件时,都需要重新启动 Metro 打包器以应用更改:

🌐 Whenever you change your babel.config.js file, you need to restart the Metro bundler to apply the changes:

Terminal
npx expo start --clear

2

使用 "use no memo" 指令可以针对特定组件或文件选择退出 React 编译器。

🌐 Use the "use no memo" directive to opt out of the React Compiler for specific components or files.

function MyComponent() { 'use no memo'; return <Text>Will not be optimized</Text>; }

用法

🌐 Usage

要更好地理解 React 编译器的工作原理,请查看 React Playground

改进主要是自动的。你可以删除 useCallbackuseMemoReact.memo 的实例,以使用自动记忆化功能。类组件将不会被优化。相反,请迁移到函数组件。

🌐 Improvements are primarily automatic. You can remove instances of useCallback, useMemo, and React.memo in favor of the automatic memoization. Class components will not be optimized. Instead, migrate to function components.

Expo 的 React Compiler 实现将仅在应用代码(无节点模块)上运行,并且仅在为客户端打包时运行(在服务器渲染中禁用)。

🌐 Expo's implementation of the React Compiler will only run on application code (no node modules), and only when bundling for the client (disabled in server rendering).

配置

🌐 Configuration

你可以通过在 Babel 配置中使用 react-compiler 对象向 React 编译器 Babel 插件传递额外的设置:

🌐 You can pass additional settings to the React Compiler Babel plugin by using the react-compiler object in the Babel configuration:

babel.config.js
module.exports = function (api) { api.cache(true); return { presets: [ [ 'babel-preset-expo', { 'react-compiler': { // Passed directly to the React Compiler Babel plugin. compilationMode: 'all', panicThreshold: 'all_errors', }, web: { 'react-compiler': { // Web-only settings... }, }, }, ], ], }; };