0day 适配不是梦:RN 0.88 鸿蒙适配背后的故事

0 评论 71 浏览 0 收藏 13 分钟

一个兴趣小组,没有排期也没有甲方,主动跟了一条 RC 线:9 月 8 日 React Native 0.88.0-rc.0 发布,他们用一周改完 120 个文件,其中真正密集动手的只有一个周六,让 RN 0.88 在鸿蒙上跑了起来。

一个兴趣小组,自愿提前跟一条 RC 线。 > 一个周六,从早上 7:51 干到晚上 21:00。 > 120 个文件的改动,一周之内,让 React Native 0.88 在鸿蒙上跑了起来。

这不是排期表上的任务,也没有甲方在催。 是我们自己想做,然后做成了。

一、0day 适配,为什么这么难

理想的形态是:官方一发版,鸿蒙当天就能用。但现实里,跨平台框架适配一个鸿蒙平台,从来不是“改个配置”那么简单。

RNOH(React Native for OpenHarmony)的适配,每次大版本升级都要同时动四个层次:

上游子模块 → 补丁基线 → ArkTS/TS 类型层 → C++ 原生层。

一层改了,下一层就得跟着验。四层全动,就意味着一整条链路重新走一遍。过去的经验是:跨版本适配,以周为单位。

而这次,我们把它压在了一周——真正密集动手的,其实只有一个周六。

二、9 月 8 日:一个需要有人拍板的决定

故事从 9 月 8 日说起。那天,上游 React Native Bot 发布了 0.88.0-rc.0。

摆在我们面前的选择很清楚:

  • 稳一稳——继续打磨刚发完的 0.86 线,等 0.88 正式版(GA)出来再动手。风险低,但等 GA 出来再适配、测试、发版,社区开发者拿到 0.88 能力最早也是几个月后。
  • 跟上去——在 RC 阶段就动手。RC 阶段 API 已基本冻结,此时适配,GA 一发布就能第一时间给出可用版本。

但官方线得优先保证稳定性,不宜跟着一条 RC 往前跑。

我把这个想法和万少沟通:我们作为兴趣小组,能不能自己先试?摸索摸索

最后万山提到:做,0day 跟。我们一起尝试

这个决定不是一时热血。摆在桌面上的理由很实在:社区开发者最怕的不是框架有 bug,而是“我用的 RN 新特性,鸿蒙上还没有”。这也是企业和社区的差异之一,当然不是说质量不重要,所以每拖一个版本,就多一批人卡在旧版本上。

0.88 这条线,也是第一个由开发者自己导演的版本。 为什么要跟、跟到哪一步、什么时候发,都是我们自己讨论、自己定的。没有外部推力,也没有交付压力。都是兴趣爱好

三、9 月 12 日:恰逢周末

9 月 12 日,周六。

后来我把这段时间的提交拉出来看,时间戳本身就是一篇故事:

时间 干了什么
07:51 基线切到 0.88.0-rc.0,补齐鸿蒙入口,SDK 升到 26.0.0
17:39 类型体系与测试用例重构
18:45 codegen specs 迁移到 CodegenTypes.* 写法
19:00 ~ 19:09 TypeScript 配置切换、清理无用测试、Node.js v26 兼容
20:57 StatusBar.DELEGATE 运行时报错修复
20:59 文档链接收尾

从早上 7:51,到晚上 21:00。中间那些 07:51 → 17:39 的间隔,是白天被事情打断、然后又坐回来的痕迹。

这就是兴趣小组的节奏——没有整块的排期,只有“能坐下来的那两小时”。

一周下来,这条线净改动 120 个文件、+24877 / -18968 行。其中光补丁文件 react-native.patch 一个,就重写了 597 行、删掉 790 行——因为上游 0.88 动的地方太多了,官方原来的补丁有一大半对不上。

四、三个最深的坑

数字看着热闹,但真正耗时间的不是“改了多少行”,而是搞清楚上游为什么变

坑一:上游把文件搬走了

这是最隐蔽的一类问题。

RNOH 的 index.js 并不指向 react-native 包,而是指向自己维护的 Libraries/ 子树。上游 0.88 把 react-private-interface 和 assets-registry 从 Libraries/ 里移除了,改成通过 package exports 暴露。

对我们的影响是:require 链直接断。但这个断裂不会在编译期暴露,而是运行时才炸——报错信息还指向内部模块路径,不查上游提交历史,根本不知道是“文件被搬走了”。

教训:跨版本升级时,“上游把文件从 A 挪到 B”比“上游删了某个 API”更危险。删 API 会编译报错,挪文件却可能一路滑到运行时。

坑二:StatusBar.DELEGATE的 ReferenceError

这是这次适配里最有含金量的一个 bug——只有真机跑起来才会暴露。

RNOH 的补丁给 StatusBar 引入了静态字段 DELEGATE,但补丁里引用它的时候,漏写了 StatusBar. 前缀

DELEGATE.setHidden(…)          // 错误:裸引用,编译期合法

StatusBar.DELEGATE.setHidden(…) // 修正:补上类前缀

为什么难查?因为它不违反语法。JS 允许裸引用未定义标识符,只有在模块加载执行到那一行时才抛错。也就是说:编译通过、打包通过、静态检查通过,一装到设备上,模块加载瞬间就炸。

一共 5 处引用,全部补上。

这类“编译期完全合法、运行时才炸”的问题,是补丁式适配特有的风险。我们改的是上游代码的副本,一旦上游结构变化导致引用上下文失效,错误就会以最隐蔽的形式出现。

坑三:宿主环境也变了

还有一个和 RN 本身无关、但会拦住 CI 的问题。

Node.js v26 把 fs.Dirent.path 重命名成了 fs.Dirent.parentPath。我们 CLI 里的消费方还在读旧名字,结果 init-harmony 的测试在新版 Node 上直接挂。

解法是兼容式降级——拿不到新字段就回退到旧的:

const parentPath = this.nodeFSDirent.parentPath ?? this.nodeFSDirent.path;

特征是:代码没错,是宿主环境变了。每次升级适配都得留一只眼睛盯着。

其余改动,压成一张清单

改动 原因
InteractionManager

从导出移除

上游把它从 RN 核心删了(连带删掉整个测试用例)
类型体系重排 0.88 把类型声明搬进了 package exports 的 conditions,testerino 得换官方 TypeScript 配置才解析得到
FlatList

/ SectionList 类型重写

上游改成 types_generated 结构
codegen 写法迁移 上游解析不了本地类型别名,得用 CodegenTypes.* 限定名
FBReactNativeSpec

整体重生成

上游改了 Fabric 组件定义,FBReactNativeSpecJSI.h 一个文件就动了 8684 行
测试用例联动改造 ListViewToken

重命名、VirtualizedList 改非泛型等

五、说清楚:这还不是严格的 0day

有一点必须摆到明面上,不然这篇文章就成了自吹。

我们不跟官方基线,跟的是 RC。 上游 0.88 正式版(GA)还没发布。所以严格来讲,这次不算 0day——真正的 0day 是“官方一发版,鸿蒙当天就能用”,而我们走的是“抢在 GA 之前把路铺好”。

那为什么还是要做?因为这次真正验证出来的,是流程跑通了

  • 补丁基线能对着新版本重新收敛,而不是每次从零猜;
  • 类型层与 codegen 的跟随方式有章可循,下次不用再改一遍;
  • 从子模块切换到发版、到 CHANGELOG 与发行说明落地,整条链路一次走完。

这次赚到的不是“快”,而是“下次能更快”。

六、这次动手的人

角色 做了什么
牵头 万少 决定跟进 0.88 RC 线
平台适配 坚果 基线切换、鸿蒙入口补齐、类型层与 codegen 适配、StatusBar.DELEGATE 修复、发版与文档落地

分工这块,这次的实际形态和 Flutter 那次(引擎 / SDK / 工具链三条线)不太一样:RNOH 这边是一条纵向链路,四层通常由同一个人串下来,因为改一层要立刻验证下一层。所以更像“一个人啃一条线,别人在各自的修复上补位”。

没有谁的付出是应该的。 这件事没有排期,能凑出来的只有周末和晚上。所以兴趣是最好的老师

七、你也可以让下一次更快

0day 不是靠某几个人堆出来的。每一个微小的参与,都在让生态往前一步。

你不需要先成为“核心贡献者”才能帮上忙:

  • 你提的一个 Issue,可能就是我们下一个版本的修复方向。特别是带着「错误堆栈 + RNOH 版本 + 设备型号」的那种;
  • 你跑通的一台设备,可能就帮生态多覆盖了一个机型。鸿蒙设备形态多,每一台都是真机验证的一环;
  • 你写的一个三方库适配,可能就让一批人少掉一个卡点;
  • 你写的一篇博客、一条反馈,可能就吸引了下一位贡献者进来。

等到上游 0.88 正式版(GA)发布的时候,我们希望做到真正的 0day。

那一次,也许就有你的身影 🚀

  • 项目地址:https://atomgit.com/oh-react-native/ohos_react_native
  • 提 Issue / 反馈问题:https://atomgit.com/oh-react-native/ohos_react_native/issues
  • 看这个版本改了什么:CHANGELOG[1] 与 0.88.0-rc.0 发行说明[2]

提 Issue、提 PR、测试反馈、交流讨论,都是对社区最好的支持。最后还是要感谢CPF-RN组织之前做的工作,才让我们社区开发者可以更快适配,或许这就是社区的意义吧

参考资料

[1]CHANGELOG: https://atomgit.com/oh-react-native/ohos_react_native/blob/main/CHANGELOG.md

[2]0.88.0-rc.0 发行说明: https://atomgit.com/oh-react-native/ohos_react_native/blob/main/docs/zh-cn/05-%E8%BF%90%E7%BB%B4/release-notes/react-native-harmony-v0.88.0-rc.0.md

本文由人人都是产品经理作者【nutpi】,微信公众号:【nutpi】,原创/授权 发布于人人都是产品经理,未经许可,禁止转载

题图来自Unsplash,基于 CC0 协议。

更多精彩内容,请关注人人都是产品经理微信公众号或下载App
海报
评论
评论请登录
  1. 目前还没评论,等你发挥!