一、简介
React 编译器会在构建时自动优化你的 React 应用
【困扰:React 的性能也已经足够快,但有时你需要手动对组件和值进行记忆化(memoization)以保持应用的响应速度。这种手动记忆化既繁琐又容易出错,并且会增加需要维护的额外代码】
- 使用之前

手动记忆化存在一个会破坏记忆化效果的细微 bug:
ini
<Item key={item.id} onClick={() => handleClick(item)} />
尽管 handleClick 被 useCallback 包裹,但每次组件渲染时,箭头函数 () => handleClick(item) 都会创建一个新的函数。这意味着 Item 总会接收到一个新的 onClick prop,从而破坏了记忆化效果
- 使用之后
使用 React 编译器,你可以编写相同的代码而无需手动进行记忆化:

二、安装
【前提条件】
React 编译器专为与 React 19 配合使用而设计,但也支持 React 17 和 18。在插件中通过target属性指定react版本进行对应的版本编译。(注意:17和18需要安装 react-compiler-runtime 包)
React 19 使用内置的 react/compiler-runtime,React 17/18 使用独立包 react-compiler-runtime
javascript
{
target: '19' // 或 '18' 和 '17'
}
【安装命令】
css
pnpm install -D babel-plugin-react-compiler @latest
注意:React 编译器必须在你的 Babel 插件管道中 首先 运行。编译器需要原始的源代码信息来进行正确的分析,因此它必须在其他转换操作之前处理你的代码
java
module.exports = {
plugins: [
'babel-plugin-react-compiler' , // 必须首先运行!
// ... 其他插件
],
// ... 其他配置
};
【ESLint集成支持】
React 编译器包含一条 ESLint 规则,可帮助识别无法优化的代码。当 ESLint 规则报告错误时,意味着编译器将跳过对该特定组件或 Hook 的优化。这是安全的:编译器将继续优化代码库的其他部分。你不需要立即修复所有违规之处。可以按照自己的节奏逐步解决这些问题,以逐渐增加已优化组件的数量。
安装
go
`npm install -D eslint-plugin-react-hooks``@latest`
参考文档:github.com/facebook/re...
【验证是否经过React编译器优化】
1、检查React DevTools
React 编译器优化的组件会在 React DevTools 中显示一个 "Memo ✨" 徽章
2、检查构建输出
编译后的代码将包含编译器自动添加的自动记忆化逻辑
【故障排查】
如果某个组件在编译后引发问题,可以使用 "use no memo" 指令暂时将其排除
csharp
function ProblematicComponent() {
"use no memo";
// 这里是组件代码
}
三、插件配置项解析
1、编译控制 - compilationMode 【控制选择要编译的函数的策略】
css
{
compilationMode: 'infer' // 或 'annotation'、'syntax' 和 'all'
}
-
'infer'(默认值):编译器使用智能的启发式方法来识别 React 组件和 Hook:- 明确使用
"use memo"指令注释的函数 - 命名类似组件(PascalCase)或 Hook(
use前缀)并且创建了 JSX 和/或调用了其他 Hook 的函数
- 明确使用
-
'annotation':仅编译使用"use memo"指示符明确标记的函数。是增量采用的理想选择。 -
'syntax':仅编译使用 Flow 的 component 和 hook 语法的组件和 Hook。【无法与ts一起使用】 -
'all':编译所有顶层函数。不推荐,因为它可能会编译非 React 函数。 -
注意:无论在哪种模式下,带有
"use no memo"指令的函数总会被跳过

2、版本兼容性 - target【确保编译器生成的代码与你的 React 版本兼容】

3、错误处理 - panicThreshold【控制编译器如何处理不遵循 React 规则 的代码,决定是让构建失败还是跳过存在问题的组件】

'none'(默认, 推荐): 跳过无法编译的组件并继续构建'critical_errors': 仅在关键编译器错误时使构建失败'all_errors': 遇到任何编译诊断即使构建失败
4、调试 - logger【为编译事件提供自定义日志功能】

方法
logEvent:传入文件名和事件详情来记录每次编译器事件
事件类型
CompileSuccess:函数成功编译CompileError: 由于错误而跳过该函数CompileDiagnostic:非致命的诊断信息CompileSkip: 因其他原因跳过该函数PipelineError: 意外的编译管线错误Timing:性能计时信息
获取详细错误日志信息

5、Feature Flags - gating【用运行时的特性开关,用于 A/B 测试或渐进式发布】
gating 选项启用条件编译,允许你控制是否在运行时使用优化代码

source:用于导入特性开关的模块路径importSpecifierName:要导入的已导出函数的名字
注意事项
- gating 函数必须返回布尔值
- 同时包含编译版本与原始版本会增加包大小
- 所有包含已编译函数的文件都会被添加该导入
用法
1、创建一个特性开关模块:

2、配置编译器:

3、编译器将生成 gated 代码:

注意:gating 函数在模块加载时只会执行一次,因此一旦 JS 包被解析并执行,组件的选择将在本次浏览器会话的剩余时间内保持不变
四、指令
React 编译器指令是特殊的字符串文字,用于控制特定函数是否被编译

可用的指令
"use memo"- 让一个函数选择加入编译[强制编译]:当使用annotation模式时,或需要覆盖infer模式的推断逻辑时"use no memo"- 让一个函数选择退出编译[阻止编译]:调试问题或处理不兼容的代码时
1、函数级别

2、模块级别
