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、模块级别

相关推荐
一只爱吃糖的小羊1 小时前
React 19 生命周期:从入门到实战的完整指南
前端·react.js
乔伊酱2 小时前
Bean Searcher 遇“鬼”记:为何我的查询条件偷偷跑进了 HAVING?
java·前端·orm
uu_code0072 小时前
字节磨皮算法详解
前端
HashTang2 小时前
【AI 编程实战】第 2 篇:让 AI 成为你的前端架构师 - UniApp + Vue3 项目初始化
前端·vue.js·ai编程
白中白121382 小时前
Vue系列-1
前端·javascript·vue.js
dorisrv2 小时前
Next.js 16 自定义 SVG Icon 组件实现方案 🎨
前端
用户新2 小时前
五万字沥血事件 深度学习 事件 循环 事件传播 异步 脱离新手区 成为事件达人
前端·javascript·事件·event loop
w2sfot2 小时前
JS代码压缩
前端·javascript·html
码途潇潇2 小时前
从组件点击事件到业务统一入口:一次前端操作链的完整解耦实践
前端