React Compiler Plugin

一、简介

React 编译器会在构建时自动优化你的 React 应用

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

  • 使用之前

手动记忆化存在一个会破坏记忆化效果的细微 bug:

ini 复制代码
<Item key={item.id} onClick={() => handleClick(item)} />

尽管 handleClickuseCallback 包裹,但每次组件渲染时,箭头函数 () => 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 的 componenthook 语法的组件和 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、模块级别

相关推荐
jacGJ1 天前
记录学习--文件读写
java·前端·学习
毕设源码-赖学姐1 天前
【开题答辩全过程】以 基于WEB的实验室开放式管理系统的设计与实现为例,包含答辩的问题和答案
前端
幻云20101 天前
Python深度学习:从筑基到登仙
前端·javascript·vue.js·人工智能·python
我即将远走丶或许也能高飞1 天前
vuex 和 pinia 的学习使用
开发语言·前端·javascript
钟离墨笺1 天前
Go语言--2go基础-->基本数据类型
开发语言·前端·后端·golang
爱吃泡芙的小白白1 天前
Vue 3 核心原理与实战:从响应式到企业级应用
前端·javascript·vue.js
卓怡学长1 天前
m115乐购游戏商城系统
java·前端·数据库·spring boot·spring·游戏
老陈聊架构1 天前
『AI辅助Skill』掌握三大AI设计Skill:前端独立完成产品设计全流程
前端·人工智能·claude·skill
Ulyanov1 天前
从桌面到云端:构建Web三维战场指挥系统
开发语言·前端·python·tkinter·pyvista·gui开发
cypking1 天前
二、前端Java后端对比指南
java·开发语言·前端