RNOH 深度解读:React Native 鸿蒙化的架构、版本、上手与生态


一、RNOH 是什么:一段话 + 一组数字

React Native for OpenHarmony(RNOH) 是在 React Native 新架构(0.68 及之后)基础上,为 OpenHarmony 增加的平台支持:业务代码仍然是 JS/TS + React,最终由鸿蒙侧的 ArkUI C-API 完成渲染、由 TurboModule 对接系统能力。对开发者来说,"React Native 的开发体验完整带入鸿蒙"意味着三件事——工程结构不变、Metro 工具链不变、三方库生态跟着走

先看组织盘子(AtomGit API 实测,2026-09-05):

RNOH 组织概览

指标数值说明
CPF-RN 组织规模286 个仓库 · 1947 Star全部为 RN 鸿蒙化相关
框架核心仓ohos_react_native ★403框架源码 + 全套中文/英文文档
三方库适配仓rntpc_* 系列 254 个react-native-svg、webview、gesture-handler、screens 等
官方适配总览表收录 442 个库条目usage-docs,标注各版本线适配状态
npm 发布域@react-native-ohos/*三方库鸿蒙化包的统一 npm 公仓坐标

演讲时可以强调:这不是一个"能跑就行的移植",而是一个带完整文档体系、版本策略、三方库流水线和测试仓(rnt、rnoh_test)的产品化工程。


二、架构:六层拆解,适配层只做两件事

RNOH 分层架构

官方《架构介绍》把 RNOH 划分为六层,自上而下:

  1. RN 应用代码:开发者写的业务代码,完全不变。
  2. RN 库代码(JS/TS 侧):React Native 在 JS 侧有大量按 Platform 判断的平台封装,鸿蒙化团队提供了 react-native-harmony 的 tgz 包,通过修改 metro.config.js 注入 Metro Bundler;Codegen 等工具链则由 react-native-harmony-cli 包适配。
  3. JSI:JavaScript 与 C++ 之间通信的接口层,JS 与原生高频互调都走这里。
  4. React Common:所有平台通用的 C++ 代码(ShadowTree、Yoga 布局、Diff),对 JS 侧数据进行预处理。JS 引擎为 Hermes 或 JSVM
  5. OpenHarmony 适配层:RNOH 的核心工作,两大支柱——
    • Fabric(组件渲染系统):接收 RN 传来的组件信息,处理后交给 OS 渲染;
    • TurboModule(能力扩展机制):为 JS 提供调用系统能力的入口。
  6. OS 代码:ArkUI C-API 的节点创建/属性设置/事件回调、图形渲染、系统能力。

2.1 Fabric 为什么快:直接对接 C-API,不走声明式范式

组件不经过 ArkUI 声明式范式的复杂流程,而是通过 ContentSlot 直接对接 ArkUI 的 C-API 后端接口渲染。官方文档给出三点性能收益:

  • C 端最小化:无跨语言的组件创建和属性设置;
  • 无数据格式转换stringenum 等不需要转成 object,CPP 侧直接用原生数据处理;
  • 属性 Diff:避免重复设置属性,降低开销。

ContentSlot 接入的两步:createSurface 时创建 ArkUISurface 并挂到 NodeContentstartSurface 时把 CPP 侧 rootView 连接到 ArkTS 侧 ContentSlot。此后子节点通过 Mutation 指令逐个插入组件树(CREATE / DELETE / INSERT / REMOVE / UPDATE 五类,由 MountingManagerCAPI::didMount 分发处理)。

2.2 TurboModule:分两类,按是否依赖系统划界

类型实现位置典型场景
ArkTSTurboModuleArkTS 侧,经 NAPI 与 CPP 通信需要调用鸿蒙系统 API 的能力,分同步/异步两种
cxxTurboModule纯 C++ 侧不依赖系统能力的模块(如 NativeAnimated 的数据计算),减少 native 与 cpp 通信次数、提高性能

2.3 线程模型:4 个线程,BACKGROUND 是实验特性

RNOH 共 4 个线程(源码 enum TaskThread):

  • MAIN:应用主线程/UI 线程,负责 ArkUI 组件生命周期(CREATE/UPDATE/INSERT/REMOVE/DELETE)、组件树管理、TurboModule 业务、交互事件;
  • JS:执行 React 代码,驱动 Render 阶段(建 ShadowTree、Yoga 布局、Diff),与 RNInstance 绑定——多实例即多 JS 线程;
  • BACKGROUND:实验特性,把部分布局和树比较任务从 JS 线程迁出以降低负荷,官方明确:正式商用版本不要开启(线程间通信复杂,有稳定性风险);
  • WORKER:RNSDK700 起新特性,让 TurboModule 跑在 worker 线程,避免与主线程 UI 绘制争抢资源,worker 内的 TurboModule 还能互相通信。

演讲要点:MAIN 和 JS 两条线程承担了全部业务,重载下可能成为瓶颈;长期演进方向是独立的 TM 线程与 TIMER 线程——这是官方文档原话,说明线程模型仍在演进期。

2.4 启动流程:四阶段,NAPI 桥共 18 个方法

启动分四阶段:RN 容器创建 → Worker 线程启动 → NAPI 方法初始化 → RN 实例创建,然后加载 bundle、渲染界面。

  • 容器创建:EntryAbilityRNApp.ets(配置 appKey、initialProps、jsBundleProvider、C-API 开关)→ 持有 RNSurface(内含 ContentSlot);
  • NAPI 初始化:RNOHAppNapiBridge.cppInit 注册 18 个 ArkTS 调 C++ 的方法(onCreateRNInstanceloadScriptstartSurfacecreateSurfaceemitComponentEvent 等);
  • RN 实例创建共 9 步:取实例 id → 注册 ArkTS 侧 TurboModule → 注册字体 → 注册系统与自定义能力 → 注册 ArkTS 混合组件 → 初始化 JS 引擎 → 注册 TM 的 JSI 通道(注入 __turboModuleProxy)→ 注入 Fabric Scheduler → 注册 Fabric JSI 通道(注入 nativeFabricUIManager);
  • 加载 bundle 的调用链:RNApp.ets > RNInstance.ts > RNOHAppNapiBridge.cpp > RNInstanceInternal.cpp > Instance.cpp

三、一次点击的旅程:渲染三阶段

渲染三阶段

官方《渲染三阶段》用一个具体 Trace 实例讲解——点击按钮,跳转到包含 1500 个 Text 组件的页面

  1. 渲染(Render,JS 线程):手势事件经适配层进入 JS 线程,React 执行业务代码创建 React 元素树;通过 JSI 频繁互调,在 C++ 侧创建 React 影子树(ShadowTree)。
  2. 提交(Commit,JS 线程):Yoga 引擎完成布局计算(文本布局通过 TextMeasurer::measure() 回调由原生侧完成,结果以 AttributedString / ParagraphAttributes / LayoutConstraints 传回 Yoga);新树与老树用 calculateShadowViewMutationsV2() 对比生成差异(mutations),送到主线程。
  3. 挂载(Mount,MAIN 线程)MountingManagerCAPI::handleMutation() 逐条执行 mutations——CREATE(建 ArkUI Node,不刷新界面)、INSERT(挂树,刷新)、UPDATE(更新属性,刷新)、REMOVE(摘下,刷新)、DELETE(删除);REMOVE_DELETE_TREE 按子树删除目前尚不支持。

这段非常适合在演讲里配合 DevEco Profiler 的线程 Trace 图讲——官方文档就是拿线程号 53130(MAIN)、53214/53216(两个 JS 实例)的真实 Trace 来讲的。


四、版本策略:四条稳定线并行 + 0.86 beta 追上游

RNOH 版本线

实测(git tag + 官方 Release Notes,2026-09-05):

版本状态说明
v0.72.143 / v0.77.74 / v0.82.33稳定线,长期维护存量应用按线升级,官方文档按 0.72/0.77/0.82 分别维护"稳定性历史修复汇总"
v0.84.3(2026-08-11)最新稳定线生产环境推荐
v0.86.3(2026-08-26)beta(内部转测 tgz)对齐上游 RN 0.86.3;edge-to-edge 支持、RN DevTools 改进;Metro ^0.84.3;内置 TurboModule 从全局 px2vp 迁移为 UIContext.px2vp(多窗口/多实例下单位换算更正确)
上游 react-nativev0.87.1RNOH 稳定线滞后上游约一个小版本,beta 已追到 0.86

版本获取机制(这是很多人踩坑的地方):

  • npm 前端包:@react-native-oh/react-native-harmony,用 dist-tag 0.XX-stable(如 0.84-stable)获取对应版本线的最新稳定版,命名对齐上游、不锁死具体版本号;
  • ohpm 原生包:@rnoh/react-native-openharmony 没有 dist-tag,必须按具体版本号安装,且前端包与原生包版本号要对齐;
  • 环境兼容范围(v0.86.3):OpenHarmony SDK API 17 – 26,最低 API 17;Node.js ≥ 20;DevEco Studio 26.0.0 Beta1(beta 基线)。

演讲要点:如果台下有人问"该用哪个版本"——生产跟随 0.84 稳定线,新项目想对齐上游新特性可以试 0.86.3 beta,并关注 Release Notes 里的破坏性变更。


五、手把手:从一台全新电脑到真机跑通

上手五步

本章假设你面前是一台没装过任何开发工具的电脑(Windows 10/11 或 macOS)。全程跟着做,最终在真机/模拟器上看到 RN 的欢迎页面。命令与约束均摘自官方《环境搭建》文档(0.86.3 基线);每一步都给了 ✅ 验证方法。

✅ 本章已实测跑通(2026-09-06,nova 12 真机 / DevEco Studio 26.0.0.821 / 构建 5 min 51 s):真机截图见 5.14 末尾,实测发现的版本选型、设备适配、签名三个关键偏差已直接修订进下文,另附实测记录 …/rnoh-lab/RUN-LOG.md

5.0 开跑之前的清单

事项要求说明
操作系统Windows 10/11 或 macOS官方文档两条平台路径都给了
Node.js≥ 20(官方要求);模板工程 engines 为 ≥ 22.11建议直接装最新 LTS,一步到位
DevEco Studio最低 6.1.0+(API 17 最低要求);0.86.3 beta 基线配套 26.0.0 Beta1从华为开发者官网下载
网络需要联网DevEco 环境配置与 npm 下载都依赖网络
华为账号1 个真机运行需要签名,自动签名要登录华为账号
磁盘建议 ≥ 50GB 可用DevEco + SDK + 工程依赖
预计耗时1.5~3 小时全量编译 C++ 较慢,首次最久

先建立全局图景——整个上手过程其实是两个工程各干各的、最后通过 bundle 交接:左边的 RN 工程负责产出 JS 代码包,右边的鸿蒙工程负责装框架、接原生、跑真机:

双工程协作全景

5.1 安装 Node.js(第 1 个工具)

  1. 打开 https://nodejs.org/,下载 LTS 版本 安装包(Windows 选 .msi,mac 选 .pkg),一路下一步。
  2. ✅ 验证:新开一个终端(PowerShell / Terminal),执行:
node -v    # 应输出 v20.x / v22.x 及以上
npm -v     # 应输出 10.x 及以上

注意:RN 的创建命令走 npx(Node 自带),不需要全局安装 react-native-cli。

5.2 安装 DevEco Studio(第 2 个工具,最大的一个)

  1. 打开 https://developer.huawei.com/consumer/cn/download/deveco-studio,下载 DevEco Studio 26.0.0 Beta1(想稳一点的团队可用 6.1.0 及以上正式版,满足 API 17 最低要求即可)。
  2. 安装完成后首次启动,按引导允许 DevEco 获取网络权限、下载 OpenHarmony SDK 与工具链——这一步官方文档明确要求联网完成"配置开发环境"。
  3. ✅ 验证:File > Settings(macOS:DevEco Studio > Preferences)里能看到已安装的 SDK 版本;欢迎页无报错。

5.3 配置 hdc(真机调试的命令行工具)

hdc 在 SDK 的 toolchains 目录下,需要手动加进 PATH。

Windows:

  1. 此电脑 > 属性 > 高级系统设置 > 高级 > 环境变量,编辑系统变量 Path,新增一条:{DevEco Studio 安装路径}\sdk\{SDK 版本}\openharmony\toolchains
  2. 同一界面"新建"系统变量:变量名 HDC_SERVER_PORT,变量值取一个没被占用的端口(如 7035)。

macOS:

vi ~/.bash_profile
# 加入两行(路径按实际 SDK 位置调整,可在 SDK 目录"显示包内容"确认):
export PATH="/Applications/DevEco-Studio.app/Contents/sdk/{版本路径}/openharmony/toolchains:$PATH"
HDC_SERVER_PORT=7035
launchctl setenv HDC_SERVER_PORT $HDC_SERVER_PORT
export HDC_SERVER_PORT
# 保存后执行:
source ~/.bash_profile

✅ 验证:新开终端执行 hdc version 能输出版本号。

5.4 打开 C-API 架构开关(环境变量)

官方 Demo 工程默认 C-API 版本,必须设置:

  • Windows:环境变量界面"新建"系统变量:RNOH_C_API_ARCH = 1
  • macOSexport RNOH_C_API_ARCH=1,写进 ~/.bash_profile(或 .zshrc)后 source 生效。

✅ 验证:Windows echo %RNOH_C_API_ARCH% / macOS echo $RNOH_C_API_ARCH 输出 1

5.5 (可选但推荐)配置 npm 镜像

编辑 C:\Users\用户名\.npmrc(macOS 为 ~/.npmrc),没有就新建:

strict-ssl=false
sslVerify=false
registry=https://repo.huaweicloud.com/repository/npm/

修改后执行 npm cache clean --force 清缓存让新源生效。(关 SSL 校验有安全代价,自行评估。)

5.6 创建 RN 工程

选一个路径不要太长的目录(后面还要建鸿蒙工程,两层路径都别深),执行:

npx @react-native-community/cli@latest init AwesomeProject --version 0.86.3
  • npx react-native init 已废弃,别用;
  • 出现 NPX has cached version != current release 警告可忽略,不影响创建;
  • macOS 上 init 会下载 iOS 依赖、耗时较长,只想搞鸿蒙可以加 --skip-install

✅ 验证:目录下生成 AwesomeProject/,里面有 package.jsonApp.tsxindex.js

5.7 安装鸿蒙化依赖

打开 AwesomeProject/package.json,加两个依赖和一个脚本:

  "scripts": {
+   "dev": "react-native bundle-harmony --dev"
  },
  "dependencies": {
+   "@react-native-oh/react-native-harmony": "0.86.3",
+   "@react-native-oh/react-native-harmony-cli": "0.86.3",
    "react": "19.2.3",
    "react-native": "0.86.3"
  }

然后安装:

npm install
# 或显式安装:
npm install @react-native-oh/react-native-harmony@0.86.3 @react-native-oh/react-native-harmony-cli@0.86.3

生产环境建议用版本线稳定版 dist-tag:npm install @react-native-oh/react-native-harmony@0.84-stable(把 0.84 换成目标线)。如何查 dist-tag 指向:npm view @react-native-oh/react-native-harmony dist-tags

⚠️ 版本选型实测(2026-09-06,重要):公共 npm 上没有 0.86.x(0.86.3 为官方"内部转测版本",未发公仓),latest tag 当前指向 0.72.143,0.84-* 只有 rc。公共渠道最新稳定组合是 RNOH 0.82.30 ↔ react-native 0.82.1——两者配套关系用 peer 依赖查最可靠:npm view @react-native-oh/react-native-harmony@0.82.30 peerDependencies。本文实测即采用该组合并跑通真机。

✅ 验证:node_modules/@react-native-oh/react-native-harmony/ 目录存在。

5.8 修改 metro.config.js

用以下内容整体替换 AwesomeProject/metro.config.js

const {mergeConfig, getDefaultConfig} = require('@react-native/metro-config');
const {createHarmonyMetroConfig} = require('@react-native-oh/react-native-harmony/metro.config');

const config = {
  transformer: {
    getTransformOptions: async () => ({
      transform: {
        experimentalImportSupport: false,
        inlineRequires: true,
      },
    }),
  },
};

module.exports = mergeConfig(getDefaultConfig(__dirname), createHarmonyMetroConfig({
  reactNativeHarmonyPackageName: '@react-native-oh/react-native-harmony',
}), config);

5.9 生成 JS bundle

npm run dev

✅ 验证:AwesomeProject/harmony/entry/src/main/resources/rawfile/ 下出现 bundle.harmony.js(有本地图片时还有 assets/ 文件夹)。

报错 "'react-native'不是内部或外部命令" → 回到工程目录重新 npm install

5.10 创建鸿蒙工程并签名

  1. DevEco Studio:File > New > Create Project,选 Empty Ability(命令行可用 devecocli create --app-name MyApplication 一键完成);
  2. Compile SDKAPI 17 及以上(RNOH 0.86.3 最低要求),工程名如 MyApplication项目路径不要太长
  3. 真机连上电脑,File > Project Structure > Signing Configs,勾选 Support HarmonyOSAutomatically generate signature,点 Sign In 登录华为账号完成自动签名。

✅ 验证:Signing Configs 里显示签名已生成(不报红)。

⚠️ 设备适配实测(装不上的头号原因):新版 DevEco 的工程模板默认 compatibleSdkVersion 较高(实测 devecocli 模板为 26.0.0),而真机系统可能更低(实测 nova 12 为 6.1.0,API 24,用 hdc shell param get const.ohos.apiversion 查询)——compatibleSdkVersion 高于设备系统会直接安装失败。解法:把根 build-profile.json5compatibleSdkVersion / targetSdkVersion 降到不高于设备的已发布 SDK 档位(如 "6.0.0(20)")。

纯命令行场景的签名实测:hvigor 在 signingConfigs 为空时会跳过签名产出 unsigned haphdc install 必失败。若无 GUI 可用,可复用本机既有自动签名材料:C:\Users\<用户>\.ohos\config\*.p7b 内含 profile 绑定的 bundleName,将应用 bundleName 改成与之一致,并从对应历史工程拷贝 signingConfigs 块(加密口令同机可复用;路径务必写正斜杠,见 5.15)。最简路径仍是 IDE 里勾一次自动签名——登录华为账号这一步无法纯 CLI 完成。

5.11 在鸿蒙工程里安装 RNOH 原生包

MyApplication/entry 目录下执行:

ohpm i @rnoh/react-native-openharmony@0.86.3

三个官方明示的注意点:

  • ohpm 没有 dist-tag,必须写具体版本号;版本号用 npm view @react-native-oh/react-native-harmony dist-tags0.XX-stable 指向的版本,前端包与原生包版本号必须对齐
  • har 包很大,安装慢属正常,务必等 ohpm install 和 IDE 自动触发的 SyncData 全部完成再编译,否则报错;
  • 工程级和模块级目录都会生成 oh_modules 文件夹,这是正常的。

✅ 验证:MyApplication/entry/oh_modules/@rnoh/react-native-openharmony/ 存在。

5.12 接入 CPP 侧(CMake + PackageProvider)

  1. MyApplication/entry/src/main 下新建 cpp 文件夹,加入 CMakeLists.txt
project(rnapp)
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_SKIP_BUILD_RPATH TRUE)
set(OH_MODULE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")

set(RNOH_CPP_DIR "${OH_MODULE_DIR}/@rnoh/react-native-openharmony/src/main/cpp")
set(RNOH_GENERATED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/generated")
set(CMAKE_ASM_FLAGS "-Wno-error=unused-command-line-argument -Qunused-arguments")
set(CMAKE_CXX_FLAGS "-fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie")
add_compile_definitions(WITH_HITRACE_SYSTRACE)
set(WITH_HITRACE_SYSTRACE 1)

add_subdirectory("${RNOH_CPP_DIR}" ./rn)

add_library(rnoh_app SHARED
    "./PackageProvider.cpp"
    "${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
)

target_link_libraries(rnoh_app PUBLIC rnoh)

自定义 CMakeLists.txt 时 so 必须命名为 rnoh_app(官方约束)。

  1. 同目录新建 PackageProvider.cpp(暂不涉及三方库,返回空数组即可):
#include "RNOH/PackageProvider.h"

using namespace rnoh;

std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
    return {};
}
  1. 打开 MyApplication/entry/build-profile.json5,把 cpp 加入构建;x86_64 模拟器要额外放开 abiFilters(默认只构建 arm64-v8a):
  "buildOption": {
+   "externalNativeOptions": {
+     "path": "./src/main/cpp/CMakeLists.txt",
+     "arguments": "",
+     "cppFlags": "",
+     // "abiFilters": ["arm64-v8a", "x86_64"]
+   }
  },

5.13 接入 ArkTS 侧(三个文件)

entry/src/main/ets/entryability/EntryAbility.ets —— 改为继承 RNAbility

import { RNAbility } from '@rnoh/react-native-openharmony';

export default class EntryAbility extends RNAbility {
  getPagePath() {
    return 'pages/Index';
  }
}

(要扩展生命周期函数时,记得调 super、参数列表与父类兼容、加 override 关键字。)

② 新建 entry/src/main/ets/RNPackagesFactory.ets

import { RNPackageContext, RNPackage } from '@rnoh/react-native-openharmony/ts';
export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
  return [];
}

entry/src/main/ets/pages/Index.ets —— RN 的页面容器(关键开关已注释):

import {
  AnyJSBundleProvider, ComponentBuilderContext, FileJSBundleProvider,
  MetroJSBundleProvider, ResourceJSBundleProvider, RNApp, RNOHErrorDialog,
  RNOHLogger, TraceJSBundleProviderDecorator, RNOHCoreContext
} from '@rnoh/react-native-openharmony';
import { createRNPackages } from '../RNPackagesFactory';

@Builder
export function buildCustomRNComponent(ctx: ComponentBuilderContext) {}

const wrappedCustomRNComponentBuilder = wrapBuilder(buildCustomRNComponent)

@Entry
@Component
struct Index {
  @StorageLink('RNOHCoreContext') private rnohCoreContext: RNOHCoreContext | undefined = undefined
  @State shouldShow: boolean = false
  private logger!: RNOHLogger

  aboutToAppear() {
    this.logger = this.rnohCoreContext!.logger.clone("Index")
    const stopTracing = this.logger.clone("aboutToAppear").startTracing();
    this.shouldShow = true
    stopTracing();
  }

  onBackPress(): boolean | undefined {
    // 返回键交给 RN 处理,不直接退出/后台
    this.rnohCoreContext!.dispatchBackPress()
    return true
  }

  build() {
    Column() {
      if (this.rnohCoreContext && this.shouldShow) {
        if (this.rnohCoreContext?.isDebugModeEnabled) {
          RNOHErrorDialog({ ctx: this.rnohCoreContext })
        }
        RNApp({
          rnInstanceConfig: {
            createRNPackages,
            enableNDKTextMeasuring: true,  // 必须为 true:开启 NDK 文本测算
            enableBackgroundExecutor: false,
            enableCAPIArchitecture: true,  // 必须为 true:开启 CAPI
            arkTsComponentNames: []
          },
          initialProps: { "foo": "bar" } as Record<string, string>,
          appKey: "AwesomeProject",
          wrappedCustomRNComponentBuilder: wrappedCustomRNComponentBuilder,
          onSetUp: (rnInstance) => {
            rnInstance.enableFeatureFlag("ENABLE_RN_INSTANCE_CLEAN_UP")
          },
          jsBundleProvider: new TraceJSBundleProviderDecorator(
            new AnyJSBundleProvider([
              new MetroJSBundleProvider(),
              new FileJSBundleProvider('/data/storage/el2/base/files/bundle.harmony.js'),
              new ResourceJSBundleProvider(this.rnohCoreContext.uiAbilityContext.resourceManager, 'hermes_bundle.hbc'),
              new ResourceJSBundleProvider(this.rnohCoreContext.uiAbilityContext.resourceManager, 'bundle.harmony.js')
            ]),
            this.rnohCoreContext.logger),
        })
      }
    }
    .height('100%')
    .width('100%')
  }
}

白屏第一诱因appKey: "AwesomeProject" 必须与 RN 侧 AppRegistry.registerComponent 注册的 appName 一致(默认就是工程名),不一致必白屏。

④ 修一个官方明示的模板坑:cli 生成的 App.tsx 依赖 safe-area-context,此时还没装这个库,会白屏——用官方给出的替换版本(用 NewAppScreen 并把 safeAreaInsets 全部置 0,移除对 safe-area-context 的依赖)覆盖 App.tsx

5.14 放入 bundle 并运行

bundle 有三种加载方式,任选其一(三种来源都会汇入 RNAppjsBundleProvider,由 AnyJSBundleProvider 按顺序尝试):

bundle 三种加载方式

  1. 本地 rawfile 加载(5.9 的产物):把 bundle.harmony.jsassets/ 放进鸿蒙工程的 entry/src/main/resources/rawfile/(上面 Index.ets 的 ResourceJSBundleProvider 会自动加载它);
  2. Metro 热加载MetroJSBundleProvider,改代码即时生效,日常开发推荐;
  3. 沙箱目录加载:用 hdc 推文件到应用沙箱,配合 FileJSBundleProvider
hdc file send ${本地bundle路径} ${应用沙箱路径}

然后 Run > Run 'entry'第一次会全量编译 C++,耗时较长,属正常,等控制台跑完。

✅ 验证:真机/模拟器出现 React Native 欢迎页,不白屏、不闪退。

📷 实测结果(2026-09-06):按本章流程在 nova 12 真机(HarmonyOS 6.1.0,API 24)上跑通——欢迎页显示 “Welcome to React Native · Version 0.82.1 · JS Engine: Hermes”,与第二章"JS 引擎为 Hermes 或 JSVM"的架构描述吻合。构建耗时 5 min 51 s(Ninja C++ 4 min 54 s,33 tasks)。截图与完整命令时间线见 …/rnoh-lab/RUN-LOG.mdrnoh-lab/rn-welcome.jpeg

5.15 新手常见报错速查

现象原因与解法
'react-native'不是内部或外部命令依赖没装全,工程目录重新 npm install
应用白屏appKeyAppRegistry.registerComponentappName 不一致;② App.tsx 依赖 safe-area-context 未替换(见 5.13-④)
编译报错、找不到 RNOH 头文件ohpm install 或 IDE SyncData 没执行完就开始编译;重试并等 Sync 完成
自定义 so 链接失败CMakeLists 里 so 没按约束命名为 rnoh_app
x86_64 模拟器上跑不起来build-profile.json5abiFilters 没放开 x86_64
hdc 连不上设备HDC_SERVER_PORT 未设置或端口被占;PATH 未含 toolchains
安装失败:设备系统低于工程要求compatibleSdkVersion 高于设备系统(实测 API 24 设备 vs 26.0.0 模板)——降到 "6.0.0(20)" 等已发布档位(见 5.10)
hvigor 00303107 Invalid storeFilesigningConfigs 里的 Windows 反斜杠路径被 JSON5 转义层吃掉——路径改用正斜杠C:/Users/...
Git Bash 里 hdc 命令的设备路径被改写MSYS 路径转换所致——命令前加 MSYS_NO_PATHCONV=1

三条高频症状的排查路径画成决策树如下(命中即改,顺序自上而下):

报错排查决策树

5.16 进阶(可选):release 包

跑通 debug 后,release 提体积与性能:npm i 后在 node_modules/@react-native-oh/react-native-harmony 里能取到两个 release 包——react_native_openharmony_release.har(cpp 编译为 .so,ts/ets 保留源码)与 react_native_openharmony_release2.har字节码格式,ts/ets 编译为 .abc,官方后续主推)。用法:放入 MyApplication/libsoh-package.json5 改为 file:../libs/...har 引用;CMake 侧把 RNOH_CPP_DIR 指到 include 目录、add_subdirectory 换成 include("${RNOH_CPP_DIR}/react-native-harmony.cmake")release2 还需在 build-profile.json5"useNormalizedOHMUrl": true;最后删 entry/oh_modulesClean ProjectSync and Refresh Project → 运行。


六、三方库生态:254 个适配仓、442 条总览、一套移植方法论

三方库是 RN 生态的命脉,也是 RNOH 投入最重的部分:

  • 规模:组织内 rntpc_* 前缀的适配仓 254 个usage-docs 的《RNOH 三方库总览》收录 442 个库条目,每条标注原库名、鸿蒙化库名、npm 地址、各版本线适配状态(0.72 / 0.77 / 0.82)与功能分类;
  • 分类覆盖:数量最多的类别是图像(13)、布局组件(13)、弹窗组件(12)、动画(10)、表单组件(9)、文本组件(9)——常用的 async-storage、camera-roll、clipboard、svg、webview、gesture-handler、screens、device-info、video 都在列;
  • 发布域:统一走 npm 公仓 @react-native-ohos/*,业务工程里把依赖名从原库换成鸿蒙化包名即可。

三条移植方法论(官方使用须知原文):

  1. Codegen 优先:三方库大部分已适配 Codegen,使用前需主动执行桥接代码生成;
  2. 只演进 C-API 架构:三方库后续只基于 RN C-API 架构演进,老架构不在长期路线上;
  3. 补丁化移植:为避免影响三方库在其他平台的行为,鸿蒙化采用补丁方式移植——这也是它能把 442 个库做成流水线的原因。

多设备场景另有专门仓库:rn_multidevice_layout_scenepkg ★31(折叠屏/平板布局)、rn_ohfeatures ★11(对齐鸿蒙特有特性)。


七、调测、性能与 AI 辅助

RNOH 的文档体系把"出问题之后怎么办"也产品化了(docs/zh-cn/ 下 03-调测、04-调优、05-运维 三个专区):

  • 调测:调试调测方法、Metro 热加载(5.14 的方式二);
  • 性能:性能优化方法、内存优化指导、最佳实践案例;稳定性专区给出标准分析路径——用 DevEco Studio 取 crash 日志/tombstone,重点关注 libRNOH.solibreact_nativemodule.so 符号,常见根因(线程未同步、NativeModule 生命周期错误、内存越界),并按 0.72 / 0.77 / 0.82 三个版本线维护"稳定性历史修复汇总";
  • AI 辅助:README 明确写道 RNOH 语料已进入 Gemini、DeepSeek、GLM 等主流 AI 模型——把"错误堆栈 + RNOH 版本 + 设备型号"喂给 AI 即可获得根因分析;组织还有 skills 仓沉淀 RN 开发技能。

测试基建同样在组织内:rnt(三方库全能力验收工程)、rnoh_test ★6(功能/性能/稳定性/兼容性测试集)。


八、共建入口:能做什么、从哪进

  1. 适配三方库:从未覆盖的 npm 库入手,参照 usage-docs 的移植方法论(Codegen + 补丁化 + C-API),成果发布到 @react-native-ohos/*
  2. 修 Issue / 同步上游:关注上游 RN 不兼容变更文档与各版本线修复汇总;
  3. 文档共建:usage-docs 中英双语、开发者共建指南(docs/zh-cn/06-社区);
  4. 测试与案例:rnt / rnoh_test 补测试用例,业务迁移案例反哺社区。

九、数据与出处

Logo

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

更多推荐