本文是《React Native x HarmonyOS NEXT 创新能力接入方案》系列第 1 篇。
本篇先完成 RNOH 环境搭建,并让一个 React Native 页面运行在 HarmonyOS 设备上,为后续接入 TTS、OCR、端侧 AI、桌面卡片等能力打基础。
源码: https://atomgit.com/huqi/RNHarmonySkuAssistant



发布成熟度

项目 状态
当前成熟度 工程桥接
资料核验时间 2026-06-04
是否代表真实 Kit 完整接入 否,除非本文后续补充真机截图、权限配置和真实 API 调用日志
发布前必须补齐 真实设备型号、SDK 版本、权限配置、构建日志、调用日志、截图

1. 本篇要实现什么?

本篇目标:

启动 Metro
    ↓
DevEco Studio 编译 HarmonyOS 工程
    ↓
安装到鸿蒙设备 / 模拟器
    ↓
页面显示 React Native 渲染的 SKU 助手首页

后续页面可以做成:

RN Harmony SKU Assistant

商品识别
商品图处理
卖点播报
库存预警

这一步的意义不是页面多复杂,而是证明:

React Native 页面已经成功跑在 HarmonyOS 上。


2. 为什么需要 RNOH?

React Native 适配 HarmonyOS NEXT 不是把 Android 包直接安装过去,而是需要 HarmonyOS 原生工程承载 React Native 运行时。

整体链路是:

React Native JS 代码
    ↓
RNOH 运行时
    ↓
HarmonyOS 原生工程
    ↓
OpenHarmony / HarmonyOS NEXT 设备

3. 技术架构说明

本系列整体架构如下:

RN Harmony SKU Assistant
├── React Native 业务层
│   ├── 页面
│   ├── 组件
│   ├── 状态管理
│   └── JS/TS 调用封装
│
├── RNOH 桥接层
│   ├── TurboModule
│   ├── Codegen
│   ├── JS ↔ ArkTS 通信
│   └── 原生模块注册
│
└── HarmonyOS 原生层
    ├── ArkTS
    ├── HarmonyOS Kit
    ├── 权限处理
    └── 系统能力调用

第 1 篇只处理:

React Native 页面
    ↓
RNOH 承载
    ↓
HarmonyOS 工程运行

4. 开发环境准备

建议准备:

Node.js
pnpm / yarn / npm
React Native
DevEco Studio
HarmonyOS SDK
RNOH
鸿蒙模拟器或真机

建议在文章中记录版本信息:

项目 当前环境
Node.js 22.x
React Native 示例为 0.84.1;实际以 RNOH 版本匹配表为准
RNOH 示例为本地源码依赖;实际以 AtomGit release/tag 与版本说明为准
DevEco Studio 6.1.1 Release
HarmonyOS SDK 6.1.1(24) / 6.1.0(23)
运行设备 HarmonyOS 6.1 模拟器/真机

实测补充:下表中的 0.84.1 是本文写作时的示例环境,不代表读者必须使用的最新版本。请先核对 AtomGit OpenHarmony-RN/ohos_react_native 的 release/tag、docs/zh-cn/05-运维/版本说明.md 与 React Native 版本匹配关系。若目标版本未发布 npm 包,可采用本地源码依赖方式接入。源码目录可放在项目同级目录:

HarmonyOS/code
├── RNHarmonySkuAssistant
└── ohos_react_native

4.1 资料核验与版本口径

本文中的版本表只记录作者当次验证环境,不等同于“最新版本推荐”。正式搭建前建议按下面顺序核验:

1. RNOH 仓库主页:OpenHarmony-RN/ohos_react_native
2. docs/zh-cn/README.md 应用开发者入口
3. docs/zh-cn/05-运维/版本说明.md
4. docs/zh-cn/05-运维/版本升级指导.md
5. 当前 release / tag 与 React Native 版本匹配关系

如果文章、截图和仓库当前 README 出现差异,以仓库文档和实际下载的 SDK / npm 包为准。


5. 创建 React Native 项目

npx @react-native-community/cli@latest init RNHarmonySkuAssistant --version <matched-rn-version>
# or 跳过 ios 等依赖的安装
# npx @react-native-community/cli@latest init AwesomeProject --version <matched-rn-version> --skip-install

cd RNHarmonySkuAssistant
npm start

或:

yarn start

我们先确认 React Native 项目可以运行:

image-20260602001245735


6. 引入 HarmonyOS 工程

  1. 打开 RNHarmonySkuAssistant 目录下的 package.json,在 scripts 下新增 OpenHarmony 的依赖:
 "name": "RNHarmonySkuAssistant",
 "version": "0.0.1",
 "private": true,
 "scripts": {
   "android": "react-native run-android",
   "ios": "react-native run-ios",
   "lint": "eslint .",
   "start": "react-native start",
   "test": "jest",
+    "harmony": "react-native bundle-harmony --dev"
 },
  1. 安装鸿蒙依赖:

    # 如果目标 RNOH 版本未发布 npm 包,可通过源码方式安装依赖;具体版本以官方版本说明为准
    # npm install @react-native-oh/react-native-harmony@<matched-version> @react-native-oh/react-native-harmony-cli --legacy-peer-deps
    
    # 下载源码,建议放在 RN 项目同级目录
    cd ..
    git clone https://atomgit.com/OpenHarmony-RN/ohos_react_native
    
    cd RNHarmonySkuAssistant
    npm install \
      file:../ohos_react_native/packages/react-native-harmony \
      file:../ohos_react_native/packages/react-native-harmony-cli \
      --legacy-peer-deps
    # 甚至我们可以通过 atomcode 来辅助安装
    

    image-20260602003525800

  2. 运行指令并生成bundle

    打开 RNHarmonySkuAssistant\metro.config.js,并添加 OpenHarmony 的适配代码:

    const {mergeConfig, getDefaultConfig} = require('@react-native/metro-config');
    const {createHarmonyMetroConfig} = require('@react-native-oh/react-native-harmony/metro.config');
    
    /**
    * @type {import("metro-config").ConfigT}
    */
    const config = {
      transformer: {
        getTransformOptions: async () => ({
          transform: {
            experimentalImportSupport: false,
            inlineRequires: true,
          },
        }),
      },
    };
    
    module.exports = mergeConfig(getDefaultConfig(__dirname), createHarmonyMetroConfig({
      reactNativeHarmonyPackageName: '@react-native-oh/react-native-harmony',
    }), config);
    
    

    运行 npm run harmony 之后 harmony/entry/src/main/resources/rawfile/bundle.harmony.js 就生成了。

    npm run harmony
    

image-20260602005223727

同时也会生成静态资源 assets 目录

image-20260602005418358

  1. 创建鸿蒙工程

    打开 DevEcho Studio 创建空白项目:

    image-20260602010450857

image-20260602010833062

项目名称:RNHarmonySkuAssistant

Bundle 名称: host.huqi.sku_assistant

路径: RNHarmonySkuAssistant/harmony/entry2

SDK: 6.1.0(23)

5 合并文件

cd harmony

# 1. 把 entry2 下除了 entry 之外的内容移到 harmony 根目录
cp -R entry2/AppScope entry2/.hvigor entry2/.idea entry2/hvigor entry2/oh_modules .

# 2. 把 entry2/entry 的内容合并到 entry/
cp -R entry2/entry/* entry/
cp -a entry2/entry/.* entry/ 2>/dev/null

# 3. 确认没问题后删除 entry2
rm -rf entry2

image-20260602011649483

当前项目最终目录采用 harmony/entry 作为唯一 entry 模块,不再保留 entry2。如果是从 DevEco 新建空白工程再合并,完成合并后要确认:

harmony
├── AppScope
├── entry
├── build-profile.json5
├── hvigorfile.ts
├── hvigor
└── oh-package.json5

entry 目录下执行命令:

ohpm i 

项目结构示例:

RNHarmonySkuAssistant
├── App.tsx
├── package.json
├── src
│   ├── pages
│   └── components
└── harmony
    ├── AppScope
    ├── entry
    ├── build-profile.json5
    └── oh-package.json5

7. 编写第一个 RN 页面

修改 App.tsx

import React from 'react';
import {
  SafeAreaView,
  ScrollView,
  StatusBar,
  StyleSheet,
  Text,
  View,
  Pressable,
} from 'react-native';

const features = [
  '商品包装 OCR 识别',
  '商品主图抠图换背景',
  '商品卖点 TTS 播报',
  '库存预警桌面卡片',
  'SKU 碰一碰分享',
];

export default function App() {
  return (
    <SafeAreaView style={styles.safeArea}>
      <StatusBar />
      <ScrollView contentInsetAdjustmentBehavior="automatic">
        <View style={styles.container}>
          <Text style={styles.title}>RN Harmony SKU Assistant</Text>
          <Text style={styles.subtitle}>
            React Native x HarmonyOS 创新能力接入方案 Demo
          </Text>

          <View style={styles.card}>
            <Text style={styles.cardTitle}>本系列将逐步实现:</Text>

            {features.map((item) => (
              <View key={item} style={styles.featureItem}>
                <Text style={styles.featureText}>{item}</Text>
              </View>
            ))}
          </View>

          <Pressable style={styles.button}>
            <Text style={styles.buttonText}>开始体验</Text>
          </Pressable>
        </View>
      </ScrollView>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  safeArea: {
    flex: 1,
    backgroundColor: '#F7F8FA',
  },
  container: {
    padding: 20,
  },
  title: {
    fontSize: 26,
    fontWeight: '700',
    color: '#111827',
    marginTop: 24,
  },
  subtitle: {
    fontSize: 15,
    color: '#6B7280',
    marginTop: 8,
    lineHeight: 22,
  },
  card: {
    backgroundColor: '#FFFFFF',
    borderRadius: 18,
    padding: 18,
    marginTop: 24,
  },
  cardTitle: {
    fontSize: 17,
    fontWeight: '600',
    color: '#111827',
    marginBottom: 12,
  },
  featureItem: {
    paddingVertical: 10,
    borderBottomWidth: StyleSheet.hairlineWidth,
    borderBottomColor: '#E5E7EB',
  },
  featureText: {
    fontSize: 15,
    color: '#374151',
  },
  button: {
    marginTop: 24,
    backgroundColor: '#0A59F7',
    borderRadius: 16,
    paddingVertical: 14,
    alignItems: 'center',
  },
  buttonText: {
    fontSize: 16,
    color: '#FFFFFF',
    fontWeight: '600',
  },
});

image-20260606011343767


8. 在 DevEco Studio 中运行 HarmonyOS 工程

运行前确认:

1. SDK 已正确配置
2. 签名配置正常
3. 设备已连接
4. Metro 已启动
5. entry 模块可以正常编译

image-20260606011455966


9. 示例环境排障记录

本文原本内置了一段较长的 0.84.1 + HarmonyOS 6.1 排障记录。为了保持环境篇主线清晰,详细过程已拆到独立文章:

附录覆盖的问题包括:

1. Metro 找不到 react-native
2. hvigor root node 报错
3. 模拟器版本与 SDK 匹配
4. safe-area-context 导致白屏
5. bundle / HAP / 安装启动验证

注意:附录是一次具体环境的排障记录,不代表所有版本都应套用相同修复。


10. 常见问题

页面白屏

优先检查:

1. Metro 是否启动
2. 设备是否能访问 Metro 地址
3. JS Bundle 是否加载成功
4. DevEco Studio 控制台是否有报错
5. RNOH 版本是否与 RN 版本匹配

如果日志中出现:

Couldn't find Turbo Module on the ArkTs side, name: 'RNCSafeAreaContext'

先不要继续反复重装模拟器。这个更像是 react-native-safe-area-context Harmony 原生包与当前 RNOH 版本的兼容问题。第一篇环境跑通阶段可以先用上面的 JS shim;后续如果业务需要真实安全区能力,再单独适配该三方包的 ArkTS / C++ TurboModule 注册。

编译失败

优先检查:

1. HarmonyOS SDK 是否安装完整
2. oh_modules 是否安装成功
3. hvigor 是否同步成功
4. 签名配置是否正确
5. RNOH 依赖版本是否一致

11. 本篇小结

本篇完成了系列第一步:

React Native 项目
    ↓
接入 RNOH
    ↓
运行在 HarmonyOS 工程中
    ↓
显示第一个 RN 页面

从下一篇开始,我们会进入真正的核心:

React Native 如何调用 HarmonyOS 原生能力?

下一篇会实现一个最小 TurboModule:

RN 页面点击按钮
    ↓
调用 ArkTS 原生模块
    ↓
返回设备信息 / Toast 结果
    ↓
RN 页面展示结果

Logo

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

更多推荐