React Compiler 可以逐步采用,让你可以先在代码库的特定部分上试用。本指南将向你展示如何在现有项目中逐步部署该编译器。

¥React Compiler can be adopted incrementally, allowing you to try it on specific parts of your codebase first. This guide shows you how to gradually roll out the compiler in existing projects.

你将学习到

  • 为什么建议逐步采用

    ¥Why incremental adoption is recommended

  • 使用 Babel 覆盖进行基于目录的采用

    ¥Using Babel overrides for directory-based adoption

  • 使用 “使用 memo” 指令进行选择加入编译

    ¥Using the “use memo” directive for opt-in compilation

  • 使用 “不使用 memo” 指令排除组件

    ¥Using the “use no memo” directive to exclude components

  • 带门控的运行时功能标志

    ¥Runtime feature flags with gating

  • 监控你的采用进度

    ¥Monitoring your adoption progress

为什么要逐步采用?

¥Why Incremental Adoption?

React Compiler 旨在自动优化你的整个代码库,但你无需一次性全部采用它。增量采用让你可以控制部署过程,让你在扩展到其余部分之前,先在应用的一小部分上测试编译器。

¥React Compiler is designed to optimize your entire codebase automatically, but you don’t have to adopt it all at once. Incremental adoption gives you control over the rollout process, letting you test the compiler on small parts of your app before expanding to the rest.

从小处着手有助于你建立对编译器优化的信心。你可以使用编译后的代码验证应用是否正常运行,衡量性能改进,并识别任何特定于代码库的边缘情况。这种方法对于稳定性至关重要的生产环境应用尤其有用。

¥Starting small helps you build confidence in the compiler’s optimizations. You can verify that your app behaves correctly with compiled code, measure performance improvements, and identify any edge cases specific to your codebase. This approach is especially valuable for production applications where stability is critical.

增量采用还可以更轻松地解决编译器可能发现的任何 React 规则违规行为。你无需一次性修复整个代码库中的违规问题,而是可以在扩展编译器覆盖范围的同时系统地解决问题。这使迁移易于管理,并降低了引入错误的风险。

¥Incremental adoption also makes it easier to address any Rules of React violations the compiler might find. Instead of fixing violations across your entire codebase at once, you can tackle them systematically as you expand compiler coverage. This keeps the migration manageable and reduces the risk of introducing bugs.

通过控制代码的哪些部分需要编译,你还可以运行 A/B 测试来衡量编译器优化对实际应用的影响。这些数据可以帮助你就是否全面采用做出明智的决定,并向你的团队展示其价值。

¥By controlling which parts of your code get compiled, you can also run A/B tests to measure the real-world impact of the compiler’s optimizations. This data helps you make informed decisions about full adoption and demonstrates the value to your team.

增量采用方法

¥Approaches to Incremental Adoption

逐步采用 React Compiler 的主要方法有三种:

¥There are three main approaches to adopt React Compiler incrementally:

  1. Babel 覆盖 - 将编译器应用于特定目录

    ¥Babel overrides - Apply the compiler to specific directories

  2. 使用 “使用 memo” 选择加入 - 仅编译明确选择启用的组件

    ¥Opt-in with “use memo” - Only compile components that explicitly opt in

  3. 运行时门控 - 使用功能开关控制编译

    ¥Runtime gating - Control compilation with feature flags

所有方法都允许你在全面推出之前在应用的特定部分测试编译器。

¥All approaches allow you to test the compiler on specific parts of your application before full rollout.

基于目录的 Babel 覆盖采用

¥Directory-Based Adoption with Babel Overrides

Babel 的 overrides 选项允许你将不同的插件应用于代码库的不同部分。这是逐步逐个目录采用 React Compiler 的理想选择。

¥Babel’s overrides option lets you apply different plugins to different parts of your codebase. This is ideal for gradually adopting React Compiler directory by directory.

基本配置

¥Basic Configuration

首先将编译器应用于特定目录:

¥Start by applying the compiler to a specific directory:

// babel.config.js
module.exports = {
plugins: [
// Global plugins that apply to all files
],
overrides: [
{
test: './src/modern/**/*.{js,jsx,ts,tsx}',
plugins: [
'babel-plugin-react-compiler'
]
}
]
};

扩展覆盖范围

¥Expanding Coverage

随着你逐渐熟悉,可以添加更多目录:

¥As you gain confidence, add more directories:

// babel.config.js
module.exports = {
plugins: [
// Global plugins
],
overrides: [
{
test: ['./src/modern/**/*.{js,jsx,ts,tsx}', './src/features/**/*.{js,jsx,ts,tsx}'],
plugins: [
'babel-plugin-react-compiler'
]
},
{
test: './src/legacy/**/*.{js,jsx,ts,tsx}',
plugins: [
// Different plugins for legacy code
]
}
]
};

使用编译器选项

¥With Compiler Options

你还可以为每个覆盖配置编译器选项:

¥You can also configure compiler options per override:

// babel.config.js
module.exports = {
plugins: [],
overrides: [
{
test: './src/experimental/**/*.{js,jsx,ts,tsx}',
plugins: [
['babel-plugin-react-compiler', {
// options ...
}]
]
},
{
test: './src/production/**/*.{js,jsx,ts,tsx}',
plugins: [
['babel-plugin-react-compiler', {
// options ...
}]
]
}
]
};

“使用 memo” 的启用模式

¥Opt-in Mode with “use memo”

为了获得最大程度的控制,你可以使用 compilationMode: 'annotation' 模式仅编译使用 "use memo" 指令明确选择的组件和钩子。

¥For maximum control, you can use compilationMode: 'annotation' to only compile components and hooks that explicitly opt in with the "use memo" directive.

注意

这种方法可以让你对单个组件和钩子进行细粒度的控制。当你想在特定组件上测试编译器而不影响整个目录时,它非常有用。

¥This approach gives you fine-grained control over individual components and hooks. It’s useful when you want to test the compiler on specific components without affecting entire directories.

注解模式配置

¥Annotation Mode Configuration

// babel.config.js
module.exports = {
plugins: [
['babel-plugin-react-compiler', {
compilationMode: 'annotation',
}],
],
};

使用指令

¥Using the Directive

在你想要编译的函数开头添加 "use memo"

¥Add "use memo" at the beginning of functions you want to compile:

function TodoList({ todos }) {
"use memo"; // Opt this component into compilation

const sortedTodos = todos.slice().sort();

return (
<ul>
{sortedTodos.map(todo => (
<TodoItem key={todo.id} todo={todo} />
))}
</ul>
);
}

function useSortedData(data) {
"use memo"; // Opt this hook into compilation

return data.slice().sort();
}

使用 compilationMode: 'annotation',你必须:

¥With compilationMode: 'annotation', you must:

  • "use memo" 添加到你想要优化的每个组件

    ¥Add "use memo" to every component you want optimized

  • "use memo" 添加到每个自定义钩子

    ¥Add "use memo" to every custom hook

  • 请记住将其添加到新组件中

    ¥Remember to add it to new components

这可以让你在评估编译器的影响时精确控制要编译的组件。

¥This gives you precise control over which components are compiled while you evaluate the compiler’s impact.

运行时功能开关及门控

¥Runtime Feature Flags with Gating

gating 选项允许你使用功能标志在运行时控制编译。这对于运行 A/B 测试或根据用户细分逐步推出编译器非常有用。

¥The gating option enables you to control compilation at runtime using feature flags. This is useful for running A/B tests or gradually rolling out the compiler based on user segments.

门控工作原理

¥How Gating Works

编译器将优化代码封装在运行时检查中。如果 gate 返回 true,则运行优化版本。否则,将运行原始代码。

¥The compiler wraps optimized code in a runtime check. If the gate returns true, the optimized version runs. Otherwise, the original code runs.

门控配置

¥Gating Configuration

// babel.config.js
module.exports = {
plugins: [
['babel-plugin-react-compiler', {
gating: {
source: 'ReactCompilerFeatureFlags',
importSpecifierName: 'isCompilerEnabled',
},
}],
],
};

实现功能标志

¥Implementing the Feature Flag

创建导出门控函数的模块:

¥Create a module that exports your gating function:

// ReactCompilerFeatureFlags.js
export function isCompilerEnabled() {
// Use your feature flag system
return getFeatureFlag('react-compiler-enabled');
}

采用故障排除

¥Troubleshooting Adoption

如果你在采用过程中遇到问题:

¥If you encounter issues during adoption:

  1. 使用 "use no memo" 暂时排除有问题的组件

    ¥Use "use no memo" to temporarily exclude problematic components

  2. 检查 调试指南 中是否存在常见问题

    ¥Check the debugging guide for common issues

  3. 修复 ESLint 插件识别出的 React 规则违规

    ¥Fix Rules of React violations identified by the ESLint plugin

  4. 考虑使用 compilationMode: 'annotation' 进行更渐进的采用

    ¥Consider using compilationMode: 'annotation' for more gradual adoption

下一步

¥Next Steps