前面讲的都是"库里有原生代码、需要把 iOS/Android 实现换成鸿蒙实现"。但社区里大量的 RN 三方库其实一行原生代码都没有——纯 JavaScript,跨平台全靠同一份 JS。

react-native-base64 就是这类库:它只有 112 行 JS,做 Base64 编解码。它不需要鸿蒙化适配。

但"不需要适配"是一个需要证明的结论,不是一个可以随口下的判断。本文要讲三件事:

  1. 怎么判断一个 RN 库要不要鸿蒙化(三步法,可复用);
  2. 怎么证明它真的不需要(与上游逐字节比对 + 零接线实测);
  3. “不需要适配"不等于"不需要验证”——实测这个库有 4 类行为边界,其中 3 类连它自己的 README 都没覆盖到或说得偏轻。

环境准备:本文不重复环境搭建步骤。RNOH(React Native for OpenHarmony)开发环境的完整配置见官方开发者指南:
https://atomgit.com/CPF-RN/docs/blob/main/开发者指南/02-搭建准备/环境初始化.md

在这里插入图片描述


一、先说结论:这个库不需要适配

判定依据(每条都实测过):

判定项结果
有没有 harmony/ 目录❌ 没有
有没有原生代码(C++ / ArkTS / HAR)❌ 没有
有没有平台分支(Platform.OS 判断)❌ 没有
有没有原生依赖❌ 没有(npm view react-native-base64 dependencies 为空)
有没有 harmony.autolinking 声明❌ 没有(package.json 里连 harmony 字段都没有)
结论✅ 纯 JS 库,直接可用

所以本文没有"六步适配步骤"那一节——因为没有适配可做。取而代之的是"判定过程"和"验证方法"。

二、判定过程:三步判断一个 RN 库要不要鸿蒙化

这个方法在选库阶段就能用,不用先装进来:

第一步:看 package.json 有没有 harmony 字段

npm view <包名> harmony --json

有 harmony.autolinking(那四个身份名)的,一定是带原生实现的适配包,必须走 link-harmony + ohpm + hvigor。

react-native-base64 的情况:

$ npm view react-native-base64 main dependencies --json
"base64.js"          # main 指向一个 JS 文件,且 dependencies 为空

第二步:看仓库里有没有 harmony/

$ git clone https://atomgit.com/oh-react-native/react-native-base64.git
$ ls react-native-base64
base64.js  package.json  LICENSE
README.OpenHarmony.md  README.OpenHarmony_CN.md
spec.json  __tests__/

没有 harmony/、没有 src/ —— 全部实现就是根目录那一个 base64.js。

第三步:读代码里有没有平台分支或原生调用

搜三个关键词就够了:

  • NativeModules / TurboModuleRegistry —— 有的话在调原生
  • Platform.OS —— 有的话在按平台分叉行为
  • requireNativeComponent —— 有的话是原生视图

base64.js 里一个都没有,就是纯字符串处理。

一个容易误判的点:node_modules 里出现 android/ 或 ios/ 目录,不代表"有原生实现"。很多库把平台工程放在包里但实际不参与 RN 运行;判断要看有没有被 JS 侧真实调用(第一步的 harmony.autolinking 是最可靠的信号)。

三、这个交付包长什么样

react-native-base64/
├── base64.js                    # 上游纯 JS 实现(★ 与 npm 上游逐字节一致)
├── package.json                 # main 指向 base64.js,无依赖
├── spec.json                    # 机器可读规格
├── README.OpenHarmony.md        # 双语说明
├── README.OpenHarmony_CN.md
├── RN_react-native-base64+代码检查报告.md
└── __tests__/base64.test.cjs    # 契约测试(node --test)

spec.json 里把性质写得很明确:

{
  "implementation": "pure JavaScript; no native module or HAR required",
  "upstream": "https://github.com/eranbo/react-native-base64",
  "upstreamCommit": "c2a2c952bfb9e458c7db2c8548a75de3be5e8e3c"
}

既然不需要适配,为什么还要建这个仓库? 我认为有三个实际价值:

  1. 可寻址:OpenHarmony 社区有统一的组织(oh-react-native)可以找到"这个库在鸿蒙上能不能用、验证到什么程度",不用每个人自己去翻上游源码判断;
  2. 可追溯:spec.json 锁死了上游 commit,说明"我验的是哪一版";
  3. 有验证记录:契约测试 + 真机场景 + 结论,比"我用过,没问题"有用得多。

但它不是改造仓库——这一点下一节会证明。

四、接入宿主:零接线

对照前面几个"需要适配"的库,这个库少了一整排接线动作:

接线项需要适配的库(带 harmony/)react-native-base64
npm install + package.json 加依赖需要需要(这个躲不掉)
react-native link-harmony需要不需要
工程级 harmony/oh-package.json5 加 HAR需要不需要
模块级 harmony/entry/oh-package.json5 加 HAR需要不需要
harmony/entry/src/main/ets/RNOHPackagesFactory.ets 注册 Package需要不需要
ohos.permission.* 权限声明视库而定不需要
metro.config.js 的 watchFolders需要本次需要一行(原因见下)

实测一:link-harmony 确实跳过了它

$ node_modules\.bin\react-native link-harmony --verbose
[link] expo-system-ui
[link] expo-video-thumbnails
[link] react-native-aes-crypto
[skip] @react-native-oh/react-native-harmony

info updated 4 file(s), linked 5 libraries, skipped 1 libraries

linked 5 libraries——和加入 base64 之前一模一样,react-native-base64 不在列表里。

实测二:Metro 的重定向清单里也没有它

[INFO] Redirected imports to 5 harmony-specific third-party package(s):
[INFO] • expo-keep-awake → expo-keep-awake
[INFO] • expo-localization → expo-localization
[INFO] • expo-system-ui → expo-system-ui
[INFO] • expo-video-thumbnails → expo-video-thumbnails
[INFO] • react-native-aes-crypto → react-native-aes-crypto

注意:这里"不在清单里"才是对的。

前面几篇我一直把这个清单当 autolinking 的自检信号——“清单里没有你的库,就说明没认出来”。对纯 JS 库这个信号要反过来读:Metro 的重定向是给"有鸿蒙变体"的包准备的(把 expo-xxx 解析到它的鸿蒙实现),纯 JS 库没有鸿蒙变体可重定向,出现在清单里反而说明有问题。

实测三:模块级 oh-package.json5 一个字没动

// harmony/entry/oh-package.json5 —— 没有 base64 的条目,构建照样成功
"dependencies": {
  "@rnoh/react-native-openharmony": "file:...",
  "@react-native-ohos/expo-keep-awake": "file:...",
  "@react-native-ohos/expo-localization": "file:...",
  "@react-native-ohos/expo-system-ui": "file:...",
  "@react-native-ohos/expo-video-thumbnails": "file:...",
  "@react-native-ohos/react-native-aes-crypto": "file:...",
}

唯一需要的一行,以及它为什么可以省

// metro.config.js
watchFolders: [
  ...
  path.resolve(__dirname, '../react-native-base64'),
],

这一行不是鸿蒙适配,而是 file: 本地依赖的通病:file: 装进 node_modules 之后是链接(Windows 上是 Junction),metro 需要一个 watchFolders 条目才认得出它的真实目录。

如果从 npm registry 装(npm install react-native-base64@0.2.2,装成真目录),连这一行都不需要——真正的"零接线"。

代价:几乎没有

上一个库(aes-crypto,带向量 JSON)本库(base64,纯 JS)
HAP 增量约 +259 KB约 +20 KB
assembleHap6 分 38 秒6 分 30 秒

纯 JS 库的接入成本几乎为零——这也是为什么"先判断要不要适配"很值:判断对了,能省掉整套原生接线和一个 30–40 分钟的首次编译。

五、验证方法:证明"真的不需要适配"

“我看了一遍代码,没有原生调用”——这不够。我用两条独立证据来说明:

证据一:交付的 JS 与 npm 上游逐字节一致

$ npm pack react-native-base64@0.2.2       # tarball 2374 字节
$ tar -xzf react-native-base64-0.2.2.tgz

适配仓库 base64.js  SHA256 = 6FE367A7EB5C3BA30EB5B9E32CB2B26EFDF1C48B006A925722CE4B9591F63063
npm 上游 base64.js  SHA256 = 6FE367A7EB5C3BA30EB5B9E32CB2B26EFDF1C48B006A925722CE4B9591F63063
==> 完全一致

哈希对上了,就说明适配仓库一行平台代码都没加——“不需要适配"从"我的判断"变成了"可核对的事实”。

顺带一个实用推论:既然字节一致,npm install react-native-base64@0.2.2 装出来的行为和这个交付仓库完全相同。

证据二:设备侧行为与 PC 端(Node)完全一致

既然是纯 JS、逻辑里没有平台分支,那它在鸿蒙的 JS 引擎上就应该和在 Node 上跑一样。我把同一份代码在两端都跑了一遍:

输入设备侧(RNOH/Hermes)PC 端(Node)一致
encode('')"AA==""AA=="✅
encode('鸿蒙')"k=""k="✅
decode('====')"Ą""Ą"✅
…(全部 8 条边界)✅

两端一字不差。这既证明"无需适配"(没有平台差异要处理),也顺带证明:下面那些行为边界是上游实现的问题,跟鸿蒙无关。

这一点很重要:如果两端不一致,那就要怀疑"是不是 JS 引擎有差异";两端一致,问题就锁定在库自己身上。

六、真机验证:31/31 通过,但更要看 C 组

验证环境:Pura X View 模拟器,HarmonyOS 7.0.0(26.0.0) Beta2,API 26,ohos-x64。

测试页分三组,刻意把"标准向量"和"行为边界"分开:

[base64-test] A. 标准向量(RFC 4648 / 字节数组 / 非法拒绝) -> 21/21 全部通过
[base64-test] B. 推荐用法(先转 UTF-8 字节) -> 10/10 全部通过
[base64-test] 边界|encode('') = "AA==" (标准期望 "")
[base64-test] 边界|encodeFromByteArray([]) = "AA==" (标准期望 "")
[base64-test] 边界|decode('') = "\0\0\0" (长度 3,标准期望 "")
[base64-test] 边界|encode("鸿蒙") = "k=" 往返不一致(数据丢失) (标准 UTF-8 应为 6bi/6JKZ)
[base64-test] 边界|encode("🔒") = "I=" 往返不一致(数据丢失) (标准 UTF-8 应为 8J+Ukg==)
[base64-test] 边界|encode("a鸿b") = "Y9i" 往返不一致(数据丢失) (标准 UTF-8 应为 Yem4v2I=)
[base64-test] 边界|encode('café') = "Y2Fm6Q==" 往返一致 (说明并非所有非 ASCII 都坏)
[base64-test] 边界|decode('====') = "Ą" (非法填充未拒绝,标准应拒绝)

在这里插入图片描述

A 组(21 项)——RFC 4648 §10 的 Base64 标准向量(f/fo/foo/foob/fooba/foobar,编码 + 解码双向)、字节数组编码、非法字符拒绝,全部对上。

B 组(10 项)——推荐用法:非 ASCII 先转 UTF-8 字节再编码,以及与标准 UTF-8 Base64 的一致性。

在这里插入图片描述

C 组(8 条)——不作为通过条件,而是把实测值原样展示出来。

在这里插入图片描述

为什么 C 组不算"通过"? 因为如果把已知偏差也塞进"通过"里,就等于把问题藏起来了。验证的目的是发现真相,不是攒一个好看的数字。

七、实测发现:四条行为边界

下面这些都是上游实现的问题(两端行为一致已经证明了),但作为交付方,我认为必须写清楚——因为其中 3 条 README 没覆盖或说得偏轻。

边界一:空串的 encode / decode 都不对

调用实测结果标准期望
base64.encode('')"AA=="""
base64.encodeFromByteArray([])"AA=="""
base64.decode('')"\0\0\0"(长度 3)""

根因:三个方法都用了 do { … } while (i < input.length) —— do...while 至少会执行一次循环体。空输入时:

// encode('') 的第一次(也是唯一一次)循环:
chr1 = ''.charCodeAt(0);          // NaN
enc1 = NaN >> 2;                  // 0
enc2 = ((NaN & 3) << 4) | (NaN >> 4);   // 0
if (isNaN(chr2)) { enc3 = enc4 = 64; }  // 成立
// keyStr.charAt(0)+charAt(0)+charAt(64)+charAt(64) = "A" + "A" + "=" + "="
// → 返回 "AA=="

decode('') 同理:keyStr.indexOf(''.charAt(0)) 也就是 indexOf('') 返回 0,四个 enc 全 0,而 enc3 != 64、enc4 != 64 都成立,于是输出三个 String.fromCharCode(0)。

这条为什么重要:空串在真实业务里很常见(用户没输入、字段为空)。encode('') 返回 "AA==" 意味着空内容会被编码成一个"看起来正常"的非空 Base64,传到下游很难排查。

边界二:非 ASCII 不是"编码不同",而是丢数据

输入实测 encode往返标准 UTF-8 Base64
"鸿蒙""k="❌ 不一致(数据丢失)6bi/6JKZ
"🔒""I="❌ 不一致(数据丢失)8J+Ukg==
"a鸿b""Y9i"❌ 不一致(数据丢失)Yem4v2I=
"café""Y2Fm6Q=="✅ 一致Y2Fmw6k=

根因:实现按 charCodeAt 取 UTF-16 码元(不是 UTF-8 字节)。当码元值超出 keyStr 的索引范围(0–64)时:

keyStr.charAt(enc1)   // enc1 = 40511 >> 2 = 10127 → 越界 → 返回空字符串 ''

数据被静默丢弃,输出还依然是个"合法 Base64 形状"的字符串。

最危险的一点是"有时对有时错":"café" 恰好往返一致(é 的码元 0xE9 落在能处理的范围内),而 "鸿蒙"、"🔒"、"a鸿b" 全部丢失。用小范围样本测试很容易漏过去——这也解释了为什么这个边界容易被忽略。

适配仓库 README 的措辞是"部分 Unicode 字符不能按 UTF-8 字节语义直接转换"。这低估了严重性:它不是"换个字节语义"的问题,而是输出丢数据、往返不一致。做交付时这种措辞应该更明确,比如直接写"非 ASCII 字符串会丢失数据,必须改走字节接口"。

边界三:畸形的填充 = 不被拒绝

base64.decode('====')  ->  "Ą"      (U+0104,长度 1)

根因:校验正则 /[^A-Za-z0-9\+\/\=]/ 把 = 当成了合法字符;随后 keyStr.indexOf('=') 返回 64,于是:

chr1 = (64 << 2) | (64 >> 4)   // 256 | 4 = 260
String.fromCharCode(260)       // "Ą"

非字母表字符确实会抛异常(实测 bad?value / a b / 中文 / Zm9v\n 四种都抛了),但畸形的填充不属于"非法字符",会被静默接受并产出垃圾。README 说"非法 Base64 字符会抛出异常"——这句话本身没错,但会让人以为"输入格式错误一定会被拦下",实际不是。

边界四:decode 返回的是"每字符一字节",不是真正的字符串

decode 内部用 String.fromCharCode(chr) 输出,所以返回的字符串里每个字符的码点就是一个字节(0–255)。对于 ASCII 这没区别;对二进制数据,拿到的是"伪字符串",要继续用就得再按字节还原:

function bytesFromDecoded(decoded: string): Uint8Array {
  const out: number[] = [];
  for (const ch of decoded) out.push(ch.charCodeAt(0) & 0xff);
  return Uint8Array.from(out);
}

这不是缺陷(上游 API 就是这样设计的),但用之前要知道。

八、正确用法:先转 UTF-8 字节

结论很简单:encode / decode 只能用于 ASCII。非 ASCII 必须走字节接口。

import base64 from 'react-native-base64';

// 编码:字符串 → UTF-8 字节 → encodeFromByteArray
const encoded = base64.encodeFromByteArray(toUtf8Bytes('鸿蒙'));   // "6bi/6JKZ",与标准一致

// 解码:decode → 每字符一字节 → 按 UTF-8 还原
const text = fromUtf8Bytes(bytesFromDecoded(base64.decode(encoded)));  // "鸿蒙"

实测 5 组(鸿蒙 / café / 🔒 / a鸿b / Hello 鸿蒙)的编码与解码全部与标准 UTF-8 Base64 一致。

toUtf8Bytes / fromUtf8Bytes 用纯 JS 写就行(别依赖 TextEncoder,RN/Hermes 不保证有全局 TextEncoder):

function toUtf8Bytes(text: string): Uint8Array {
  const out: number[] = [];
  for (const ch of text) {
    const cp = ch.codePointAt(0) ?? 0;
    if (cp < 0x80) out.push(cp);
    else if (cp < 0x800) out.push(0xc0 | (cp >> 6), 0x80 | (cp & 0x3f));
    else if (cp < 0x10000) out.push(0xe0 | (cp >> 12), 0x80 | ((cp >> 6) & 0x3f), 0x80 | (cp & 0x3f));
    else out.push(0xf0 | (cp >> 18), 0x80 | ((cp >> 12) & 0x3f), 0x80 | ((cp >> 6) & 0x3f), 0x80 | (cp & 0x3f));
  }
  return Uint8Array.from(out);
}

空串要调用方自己兜底:

const encode = (s: string) => (s.length === 0 ? '' : base64.encode(s));
const decode = (s: string) => (s.length === 0 ? '' : base64.decode(s));

更省事的做法是换掉它。 如果项目里只是要标准的 Base64,用 js-base64 这类维护活跃、语义正确的库更直接。这个交付仓库的价值是"上游原样 + 已验证可用性边界",不是"推荐优先选它"。我把边界写这么细,正是为了让读者能自己判断该不该用。

九、已知限制

一、encode / decode 不适用于非 ASCII。 会丢数据且往返不一致(边界二)。必须改走 encodeFromByteArray + 自己转 UTF-8 字节。

二、空串 / 空数组行为不正确。 encode('') 与 encodeFromByteArray([]) 返回 "AA==",decode('') 返回 "\0\0\0"(边界一)。需要调用方兜底。

三、畸形填充不被拒绝。 decode('====') 返回 "Ą" 而不是抛错(边界三)。不能依赖这个库做"输入合法性"的第一道防线。

四、没有标准的 Unicode 支持。 这是上游的设计边界——它的定位是"ASCII / 单字节字符串的 Base64",不是完整的 UTF-8 编解码器。

五、本次只验证了三个公开方法。 上游也只有这三个(encode / encodeFromByteArray / decode)。

六、大字符串的吞吐与性能未测。 纯 JS 实现对小字符串没问题,长字符串的性能未做基准测试。

七、其他 ROM / 真机未验证。 本次在 HarmonyOS 7.0.0(26.0.0) Beta2 模拟器上通过;适配方记录的是 OpenHarmony-7.0.0.105。

八、没有修改库代码。 上述行为边界属上游实现,按任务边界只做记录与用法建议。

十、常见问题

Q:这个库为什么不用适配?
A:它是纯 JavaScript 实现——没有 harmony/、没有原生代码、没有平台分支、没有原生依赖。RN 的 JS 代码在 RNOH 上跑的是同一个 JS 引擎(Hermes),不需要"把 iOS/Android 实现换成鸿蒙实现"这一步。实测设备侧行为与 Node 端完全一致。

Q:那我怎么知道别的库要不要适配?
A:三步:① npm view <包名> harmony --json 看有没有 harmony.autolinking;② 仓库里有没有 harmony/;③ 代码里有没有 NativeModules / Platform.OS / requireNativeComponent。第一条最可靠。

Q:既然不需要适配,为什么还有这个仓库?
A:它是交付与验证仓库,不是改造仓库。价值在于"可寻址 + 可追溯 + 有验证记录":社区能查到"这个库在鸿蒙上能不能用、验到什么程度",spec.json 锁死了上游 commit。它的 base64.js 与 npm 上游 SHA256 完全一致,一行平台代码都没加。

Q:我 npm install react-native-base64 装的是这个仓库的版本吗?
A:npm 上的同名包是上游包,但因为交付仓库的 JS 与上游逐字节一致,行为完全相同。从 npm 装反而更省事(真目录,连 metro.config.js 的 watchFolders 都不用加)。

Q:为什么我 encode('') 得到 "AA=="?
A:上游实现的 do...while 循环至少会执行一次,空输入时 charCodeAt 返回 NaN,位运算后落到索引 0 和填充位 64,拼出 "AA=="。这是上游问题,不是鸿蒙问题——Node 端跑同样的代码结果一样。调用方自己兜底空串。

Q:为什么我 encode('鸿蒙') 得到 "k=",而且解不回来?
A:因为它按 UTF-16 码元处理,码元值超出 keyStr 索引范围时 charAt 返回空串,数据被静默丢弃。正确做法是先转 UTF-8 字节再 encodeFromByteArray。注意 'café' 这种恰好能往返——别用小样本判断"支持不支持 Unicode"。

Q:decode('====') 为什么不报错?
A:校验正则把 = 当成合法字符,所以畸形填充绕过了检查,indexOf('=') = 64 参与位运算后产出 "Ą"。别把这个库当作输入校验的手段。

Q:decode 出来的字符串怎么再变成字节?
A:它返回的是"每字符一字节"的 JS 字符串,for (const ch of s) bytes.push(ch.charCodeAt(0) & 0xff) 即可还原成 Uint8Array。

Q:为什么我在 metro.config.js 里加了 watchFolders 却没有在别的库那里加?
A:这一行不是鸿蒙适配,是 file: 本地依赖的通病——file: 装进 node_modules 是链接(Junction),metro 需要 watchFolders 才认真实目录。从 npm registry 装成真目录就不需要这一行。

Q:怎么确认纯 JS 库"真的没被 autolinking 接管"?
A:看 link-harmony 的输出——linked N libraries 的 N 不应该因为它增加;以及 Metro 的 Redirected imports to N ... 清单里不应该出现它。注意这个信号和带原生实现的库是反的:那些库"不在清单里"是坏事,纯 JS 库"不在清单里"是好事。

小结

这篇的结论和前面几篇不一样,收获也不一样:

  • "不需要适配"是一个需要证明的结论。 我不满足于"看了一下没有原生调用",而是用两条独立证据把它钉死:① 交付的 base64.js 与 npm 上游SHA256 完全一致(一行平台代码都没加);② 设备侧与 PC 端(Node)行为逐字节一致(没有平台差异要处理)。第二条还顺带把"行为边界是上游问题还是鸿蒙问题"这件事一并锁定了。
  • “不需要适配"不等于"不需要验证”。 恰恰因为纯 JS 库"看起来一定能用",最容易跳过验证——而这个库实测有 4 类行为边界,其中 3 类连它自己的 README 都没覆盖到:空串会编码成 "AA=="、非 ASCII 会丢数据、畸形填充不被拒绝。"能跑"和"用对"是两件事。
  • 判断对了能省很多。 一个纯 JS 库的接入成本是"加一行依赖"(+20 KB HAP、6 分 30 秒编译);一个带原生实现的库是"三处接线 + 一个 30–40 分钟的首次编译"。选库阶段花五分钟做判断,比装进来再发现要适配划算得多。
  • 交付措辞要够准。 README 写"部分 Unicode 字符不能按 UTF-8 字节语义直接转换",字面没错,但读者会低估成"结果是另一种编码"。实际是丢数据、往返不一致。做技术交付时,把边界说到位比说得委婉重要。

最后一条关于验证心态:这次我刻意把"C 组行为边界"排除在通过率之外,而不是把它们算进"31/31"。因为把已知偏差塞进"通过"里,就只是把问题藏起来——验证的目的是发现真相,不是攒一个好看的数字。这个习惯在密码学那篇(rn-05)能给出 159/159 的硬结论,在这个库则能给出"31/31 通过,但有 4 条必须知道的边界"这样的完整结论。


本篇用到的库

项内容
三方库react-native-base64(上游 0.2.2,纯 JS 实现)
交付仓库https://atomgit.com/oh-react-native/react-native-base64
适配 TAG0.2.2-ohos-1.0.0
是否需要 HAR / ohpm / autolinking都不需要
上游仓库https://github.com/eranbo/react-native-base64
基线 commitc2a2c952bfb9e458c7db2c8548a75de3be5e8e3c
宿主工程RNOH084Demo(测试页 rnAppKey = Base64TestApp)
"react-native-base64": "git+https://atomgit.com/oh-react-native/react-native-base64.git#0.2.2-ohos-1.0.0"
// 只对 ASCII 安全
import base64 from 'react-native-base64';
base64.encode('Some string');              // "U29tZSBzdHJpbmc="
base64.decode('U29tZSBzdHJpbmc=');         // "Some string"

// 非 ASCII 必须走字节接口
base64.encodeFromByteArray(toUtf8Bytes('鸿蒙'));   // "6bi/6JKZ"

// 空串要自己兜底(否则得到 "AA==")
const encode = (s: string) => (s.length === 0 ? '' : base64.encode(s));
# 换页启动测试页(force-stop 不能省,换页参数只在冷启动生效)
hdc shell aa force-stop com.rnoh084.demo
hdc shell aa start -b com.rnoh084.demo -a EntryAbility --ps rnAppKey Base64TestApp

验证环境

项版本
React Native0.84.1
React19.2.3
RNOH(npm / ohpm)@react-native-oh/react-native-harmony / @rnoh/react-native-openharmony 0.84.3
Node.jsv24.14.0
DevEco Studio26.0.0.621
HarmonyOS SDKAPI 26(26.0.0.32)
设备HarmonyOS 7.0.0(26.0.0) Beta2 模拟器 Pura X View(ohos-x64)
宿主 HAP 产物entry-default-signed.hap(80.0 MB)
本次增量构建assembleHap 6 分 30 秒(改 JS 后重编 6 分 25 秒)
验证规模设备侧 31 项断言全通过 + 8 条行为边界实测;与 npm 上游 SHA256 一致

欢迎加入 CPF-RN 鸿蒙社区:https://atomgit.com/CPF-RN

React Native for OpenHarmony 组织:https://atomgit.com/oh-react-native

RN 三方库鸿蒙适配清单:https://atomgit.com/oh-react-native/rn-ohos-adaptation-overview

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐