关于这次体验

这是一次在鸿蒙PC上本地开发React Native应用的完整体验。如果你手上有一台鸿蒙PC,想尝试在本机上直接开发跨平台应用,这份文档会带你走完整个流程。

与传统的跨平台开发不同,你不需要Windows或Mac作为开发主机——所有开发工作都在鸿蒙PC上完成。


目录

  1. 体验前的准备
  2. 环境搭建
  3. 创建React Native项目
  4. 在鸿蒙原生工程中运行
  5. 常见问题处理
  6. 关键技术要点

一、体验前的准备

需要准备的硬件和环境

  • 一台鸿蒙PC(HarmonyOS PC版本 6.1.0 +)
  • 稳定的网络连接(用于下载SDK和依赖包)
  • 基础的命令行操作能力(会用终端执行简单命令)
  • 可选:一台鸿蒙手机或平板(用于真机测试,也可以用模拟器)

本次体验包含的内容

  • 在鸿蒙PC上安装并配置DevEco Studio
  • 创建一个React Native项目
  • 在鸿蒙设备上运行这个应用
  • 理解开发流程中的关键步骤

二、环境搭建

1. 安装 DevEco Studio

DevEco Studio 是鸿蒙应用开发的官方IDE,类似于Android开发中的Android Studio。

  1. 申请鸿蒙PC专用版本
    访问官方申请页面:https://developer.huawei.com/consumer/cn/activity/developerbeta/deveco-studio-preview

    申请后会有审核,审核通过了就会发送邮件至邮箱中,点击邮件中的链接就可以进行安装了。

  2. 下载并安装
    按照页面提示下载安装包,双击安装即可

  3. 首次启动配置

    • 启动DevEco Studio
    • 按照向导完成SDK下载(选择OpenHarmony SDK)
    • 配置网络代理(如果需要)

2. 配置 hdc 调试工具

hdc 是鸿蒙的命令行调试工具,类似于Android的adb。需要把它加入到系统环境变量中。

配置步骤
  1. 下载Harmonybrew

    安装指南:docs/zh-CN/user/install.md-代码预览-docs:基于 OpenHarmony 的包管理器移植项目 - AtomGit

    Harmonybrew 是鸿蒙 / OpenHarmony 专用命令行软件包管理器,照搬 macOS 主流工具 Homebrew 的逻辑,一键下载 gcccmakeohos-sdk 等开发工具,不用手动找安装包、配依赖。

  2. 打开终端-验证brew安装成功

    localhost ~ % brew --version
    

    如果显示版本号,说明配置成功。

  3. 安装ohos-sdk**

    localhost ~ % brew install ohos-sdk
    

    下载ohos-sdk后,hdc工具自动配置。

  4. 验证是否配置成功

    hdc --version
    

    如果显示版本号,说明配置成功。

3. 配置 CAPI 架构环境变量

这是React Native在鸿蒙上运行的必要配置。

配置步骤
  1. 继续编辑 ~/.zshrc

    vim ~/.zshrc
    
  2. 添加环境变量

    export RNOH_C_API_ARCH=1
    
  3. 保存后生效

    source ~/.zshrc
    
  4. 验证

    echo $RNOH_C_API_ARCH
    

    应该输出 1

4. 配置 npm 镜像源

使用国内镜像可以加速依赖包下载。

配置步骤
  1. 编辑 npm 配置文件

    vim ~/.npmrc
    
  2. 添加以下内容(按 i 进入编辑模式)

    strict-ssl=false
    sslVerify=false
    registry=https://repo.huaweicloud.com/repository/npm/
    
  3. 保存并退出(按 Esc,输入 :wq 回车)

  4. 清理缓存使配置生效

    npm cache clean --force
    

5. 连接调试设备

真机使用流程
  1. 在设备上开启开发者模式

    • 设置 → 关于手机/平板 → 连续点击版本号7次
    • 返回设置 → 系统和更新 → 开发者选项 → 开启USB调试
  2. 用USB连接设备到鸿蒙PC

  3. 验证连接

    hdc list targets
    

    应该显示设备序列号


三、创建你的第一个RN应用

1. 初始化React Native项目

打开终端,执行以下命令:

# 创建项目(项目名可以自定义)
npx @react-native-community/cli@latest init AwesomeProject --version 0.77.1  --skip-install

提示:首次执行会下载一些依赖,可能需要几分钟时间。

2. 进入项目目录

cd AwesomeProject

3. 安装鸿蒙适配依赖

步骤 1:修改 package.json

用文本编辑器打开 package.json,在 scripts 部分添加一行:

{
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "start": "react-native start",
    "dev": "react-native bundle-harmony --dev"  // 添加这一行
  }
}
步骤 2:安装鸿蒙专用包
npm install @react-native-oh/react-native-harmony@0.77.59 @react-native-oh/react-native-harmony-cli --legacy-peer-deps

说明:本文以0.77.59RNOH版本为例,可以去官网搜索React Native和RNOH对应版本。

4. 配置 Metro 打包工具

Metro 是React Native的JavaScript打包工具。需要让它支持鸿蒙平台。

修改 metro.config.js

用文本编辑器打开项目根目录的 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. 生成鸿蒙 bundle 文件

npm run dev

成功后,你会在 harmony/entry/src/main/resources/rawfile/ 目录下看到:

  • bundle.harmony.js - 打包后的JavaScript代码
  • assets/ - 静态资源文件夹
  • 将rawfile/ 目录下的所有文件复制到 后面第四步创建的鸿蒙原生工程MyApplication/entry/src/main/resources/rawfile/

四、在鸿蒙原生工程中运行

1. 用 DevEco Studio 打开鸿蒙工程

  1. 启动 DevEco Studio
  2. FileNewCreate ProjectEmpty Ability
  3. 点击 Next 按钮,创建一个名为 “MyApplication” 的项目

2. 配置签名(首次必须)

  1. FileProject StructureSigning Configs
  2. 登录你的华为开发者账号
  3. 点击 Apply → OK

3. 安装鸿蒙 HAR 依赖包

在 DevEco Studio 的终端中执行:

cd entry
ohpm install @rnoh/react-native-openharmony@0.77.59

注意:这个包比较大(几百MB),下载需要一些时间。等待 ohpm install 完成后,IDE会自动同步依赖。

4. 配置 C++ 底层代码

React Native需要通过C++层来桥接JavaScript和鸿蒙原生代码。

步骤 1:创建 C++ 目录和文件

harmony/entry/src/main/ 下创建 cpp 文件夹,然后创建以下文件:

文件 1: 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
    "./RNOHAppNapiBridge.cpp"
)

target_link_libraries(rnoh_app PUBLIC rnoh)

文件 2: cpp/PackageProvider.cpp

#include "RNOH/PackageProvider.h"
#include "RNOHCorePackage/RNOHCorePackage.h"

using namespace rnoh;

std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
    return {
        std::make_shared<RNOHCorePackage>(ctx),
    };
}

重要提示:如果你只返回空数组 {},应用会崩溃并提示 undefined is not callable。必须注册 RNOHCorePackage

文件 3: cpp/RNOHAppNapiBridge.cpp

#include "RNOH/PackageProvider.h"
#include "RNOHCorePackage/RNOHCorePackage.h"

using namespace rnoh;

std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
    return {
        std::make_shared<RNOHCorePackage>(ctx),
    };
}

#include "../../../oh_modules/@rnoh/react-native-openharmony/src/main/cpp/RNOHAppNapiBridge.cpp"
步骤 2:配置构建选项

编辑 harmony/entry/build-profile.json5,添加 C++ 编译配置:

{
  "apiType": "stageMode",
  "buildOption": {
    "externalNativeOptions": {
      "path": "./src/main/cpp/CMakeLists.txt",
      "arguments": "",
      "cppFlags": ""
    }
  },
  "targets": [
    {
      "name": "default"
    }
  ]
}

5. 配置 ArkTS 页面代码

步骤 1:修改 EntryAbility.ets

打开 harmony/entry/src/main/ets/entryability/EntryAbility.ets,替换为:

import { RNAbility } from '@rnoh/react-native-openharmony';
import { Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';

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

  // ⚠️ 非常重要:必须先调用 super.onCreate()
  override onCreate(want: Want): void {
    super.onCreate(want);  // 这一行必须放在第一行!
    hilog.info(0x0000, 'testTag', '%{public}s', 'EntryAbility onCreate');
  }
}

关键点super.onCreate(want) 这行代码会初始化React Native运行时环境。如果忘记调用,应用会崩溃并提示 Cannot read property logger of undefined

步骤 2:创建 RNPackagesFactory.ets

harmony/entry/src/main/ets/ 目录下创建 RNPackagesFactory.ets

import { RNPackageContext, RNPackage } from '@rnoh/react-native-openharmony/ts';

export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
  return [];
}
步骤 3:修改首页 Index.ets

打开 harmony/entry/src/main/ets/pages/Index.ets,替换为以下内容:

import {
  AnyJSBundleProvider,
  ComponentBuilderContext,
  FileJSBundleProvider,
  MetroJSBundleProvider,
  ResourceJSBundleProvider,
  RNApp,
  RNOHErrorDialog,
  RNOHLogger,
  TraceJSBundleProviderDecorator,
  RNOHCoreContext,
  wrapBuilder
} 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 {
    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,
            enableBackgroundExecutor: false,
            enableCAPIArchitecture: true,
            arkTsComponentNames: []
          },
          initialProps: { "foo": "bar" } as Record<string, string>,
          // ⚠️ 重要:这里必须和你的RN项目名完全一致
          appKey: "AwesomeProject",
          wrappedCustomRNComponentBuilder: wrappedCustomRNComponentBuilder,
          onSetUp: (rnInstance) => {
            rnInstance.enableFeatureFlag("ENABLE_RN_INSTANCE_CLEAN_UP")
          },
          jsBundleProvider: new TraceJSBundleProviderDecorator(
            new AnyJSBundleProvider([
              new MetroJSBundleProvider(),
              new ResourceJSBundleProvider(
                this.rnohCoreContext.uiAbilityContext.resourceManager, 
                'bundle.harmony.js'
              )
            ]),
            this.rnohCoreContext.logger
          ),
        })
      }
    }
    .height('100%')
    .width('100%')
  }
}

关键配置说明

  • appKey: "AwesomeProject" - 必须和你的RN项目名完全一致(包括大小写)
  • MetroJSBundleProvider() - 支持热加载,开发时非常方便
  • ResourceJSBundleProvider - 从应用资源加载bundle文件

6. 启动Metro服务(推荐)

在React Native项目根目录(AwesomeProject)打开终端,执行:

npm run start

这会启动Metro开发服务器,支持代码热更新。

7. 运行应用

  1. 在DevEco Studio中,确保已连接设备
  2. 点击工具栏的 Run 按钮(绿色三角形)
  3. 选择 entry 模块
  4. 等待编译完成(首次编译需要几分钟)

如果一切顺利,你会在设备上看到React Native的欢迎界面!🎉


五、遇到问题怎么办

常见问题 1:应用崩溃,提示 Cannot read property logger of undefined

原因EntryAbility.ets 中忘记调用 super.onCreate(want)

解决方法

  1. 打开 harmony/entry/src/main/ets/entryability/EntryAbility.ets
  2. 确保 onCreate 方法的第一行是 super.onCreate(want);

常见问题 2:应用崩溃,提示 undefined is not callable

原因PackageProvider.cpp 中没有注册 RNOHCorePackage

解决方法

  1. 打开 harmony/entry/src/main/cpp/PackageProvider.cpp

  2. 确保代码如下:

    #include "RNOH/PackageProvider.h"
    #include "RNOHCorePackage/RNOHCorePackage.h"
    
    using namespace rnoh;
    
    std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
        return {
            std::make_shared<RNOHCorePackage>(ctx),  // 这行很重要
        };
    }
    

常见问题 3:白屏,提示 Couldn't run a JS bundle

原因:bundle文件没有正确生成或加载

解决方法

  1. 在项目根目录执行 npm run dev
  2. 检查 harmony/entry/src/main/resources/rawfile/bundle.harmony.js 是否存在
  3. 确保 Index.ets 中的 appKey 和项目名一致

常见问题 4:编译失败,找不到 librnoh_app.so

原因:C++ 配置不正确

解决方法

  1. 检查 harmony/entry/build-profile.json5 是否配置了 externalNativeOptions
  2. 检查 harmony/entry/src/main/cpp/CMakeLists.txt 是否存在
  3. 在 DevEco Studio 中执行:Build → Clean Project,然后重新构建

查看详细日志

如果遇到其他问题,可以通过日志来诊断:

# 实时查看设备日志
hdc shell hilog

六、技术要点说明

1. React Native 在鸿蒙上的架构

React Native 应用在鸿蒙上分为三层:

  • JavaScript 层:你写的React代码
  • ArkTS 层:鸿蒙的UI层
  • C++ 桥接层:连接JS和鸿蒙原生能力

三层缺一不可,任何一层配置错误都会导致应用无法运行。

2. appKey 的作用

appKey 不是一个随便取的名字,它是JavaScript和原生代码的约定:

  • JavaScript侧:AppRegistry.registerComponent('AwesomeProject', ...)
  • 原生侧:appKey: "AwesomeProject"

两边必须完全一致(包括大小写),否则应用会白屏。

3. 为什么需要 super.onCreate()

RNAbility 是React Native提供的基类,它的 onCreate() 方法会初始化整个运行时环境。如果你重写了这个方法却不调用 super.onCreate(),运行时环境就无法初始化,导致应用崩溃。

4. Metro 开发服务器的作用

Metro 是React Native的打包工具:

  • 开发模式:启动本地服务器,支持热更新(改代码立即生效)
  • 生产模式:打包成 .js 文件,内嵌到应用中

开发时推荐使用Metro模式,可以大幅提升效率。

5. bundle 加载优先级

Index.ets 中配置了多种加载方式:

  1. MetroJSBundleProvider - 优先从Metro服务器加载(开发模式)
  2. ResourceJSBundleProvider - 从应用资源加载(生产模式)

应用会按顺序尝试,找到第一个可用的就使用。


七、下一步探索

修改代码试试

  1. 在项目根目录打开 App.tsx
  2. 修改一些文字,比如把 “Welcome to React Native” 改成 “你好,鸿蒙!”
  3. 保存文件
  4. 如果Metro服务正在运行,应用会自动刷新

添加新的组件

React Native 提供了很多内置组件,你可以试试:

import { View, Text, Button, Alert } from 'react-native';

function App() {
  return (
    <View>
      <Text>Hello HarmonyOS!</Text>
      <Button 
        title="点击我" 
        onPress={() => Alert.alert('你点击了按钮')} 
      />
    </View>
  );
}

学习更多

  • React Native 官方文档:https://reactnative.dev/
  • React Native 中文网:https://reactnative.cn/
  • RNOH 官方仓库:https://gitee.com/openharmony-sig/ohos_react_native
  • 鸿蒙开发者文档:https://developer.harmonyos.com/

七、体验感悟

开发体验的亮点

1. 本地化开发的便利性

在鸿蒙PC上直接开发React Native应用,最大的感受是一体化。不需要在Windows和设备之间来回切换,所有工作都在一台设备上完成:

  • 编写代码、调试、运行,全程本地
  • 设备之间的数据同步更流畅(如果用鸿蒙账号)
  • 终端、IDE、文档可以在同一个工作区管理
2. Metro 热更新的开发效率

使用 Metro 开发服务器后,代码修改几乎是秒级生效。这种即时反馈的开发体验非常适合UI调试和快速迭代:

修改代码 → 保存 → 设备自动刷新(< 2秒)

相比传统的"改代码 → 重新编译 → 重新安装",效率提升了一个数量级。

3. C++ 层的学习曲线

React Native 在鸿蒙上需要配置 C++ 桥接层,这对前端开发者来说可能是一个挑战。但好在:

  • 模板化:大部分 C++ 代码是固定的模板
  • 一次配置:配置好后基本不需要再改动
  • 文档完善:RNOH 社区提供了详细的参考

经过这次体验,对 React Native 的架构理解更深了——它不仅仅是 JavaScript 框架,而是一个完整的跨平台桥接系统。

遇到的挑战

1. 首次构建的耗时

第一次编译 C++ 代码时,时间确实比较长(5-10分钟)。这是因为:

  • 需要编译 RNOH 的完整 C++ 库
  • 需要链接大量的依赖
  • 首次构建会做完整的依赖检查

建议:首次构建时可以去喝杯咖啡,后续的增量编译会快很多。

2. 错误信息的理解

当配置不正确时,错误信息有时不够直观。比如:

  • Cannot read property logger of undefined → 实际是 super.onCreate() 没调用
  • undefined is not callable → 实际是 PackageProvider 没注册

经验:遇到错误时,先检查文档中"常见问题"部分列出的那几个关键点,90%的问题都在那里。

3. 依赖包的下载速度

由于网络原因,ohpm installnpm install 有时会比较慢。特别是 @rnoh/react-native-openharmony 这个包体积较大。

解决方案:配置好镜像源后情况会好很多,华为云的镜像源速度还是很可靠的。

与传统开发的对比

传统方式(Windows/Mac + 鸿蒙设备)
代码编辑 (PC) → 编译打包 (PC) → 传输到设备 → 运行测试 → 查看日志 (PC)
  • 优点:PC性能强,编译快
  • 缺点:需要维护跨设备的开发环境,调试链路长
鸿蒙PC本地开发
代码编辑 → Metro热更新 → 即时预览 → 查看日志 → 继续编辑
  • 优点:一体化,调试链路短,移动办公友好
  • 缺点:首次编译耗时较长

适合的场景

通过这次完整体验,我认为鸿蒙PC本地开发特别适合以下场景:

  1. 原型快速验证
    需要快速搭建一个 Demo,验证想法的可行性

  2. UI 交互调试
    频繁调整界面布局、动画效果,需要即时反馈

  3. 移动办公
    只带一台鸿蒙PC出差或远程工作,也能完成开发任务

  4. 学习和实验
    学习 React Native 或鸿蒙开发,体验完整的技术栈

不太适合的场景

  1. 大型项目的重度开发
    如果项目有几十个原生模块,构建时间会比较长

  2. 需要频繁切换平台调试
    如果需要同时调试 Android、iOS、鸿蒙三端,在PC上可能更方便

未来的期待

经过这次体验,对鸿蒙PC作为开发平台有了信心。如果未来能有以下改进,体验会更好:

  1. 增量编译优化
    希望 C++ 层的编译速度能进一步提升

  2. 更友好的错误提示
    特别是配置错误时,能给出更明确的定位

  3. 开发工具链完善
    比如支持更多的调试工具、性能分析工具

  4. 社区生态丰富
    更多的第三方库适配鸿蒙平台

总体评价

作为一次尝鲜体验,在鸿蒙PC上开发 React Native 应用是可行且流畅的。虽然有一些小挑战,但并不妨碍完整走通开发流程。

推荐指数:⭐⭐⭐⭐(4/5)

  • 如果你是鸿蒙PC用户,想尝试跨平台开发 → 强烈推荐体验
  • 如果你在学习React Native → 这是一个很好的实践平台
  • 如果你是移动办公族 → 一台设备完成开发的体验很棒

最大的收获:理解了 React Native 的完整架构,从 JavaScript 到原生桥接,再到设备运行,整个链路清晰了。


八、版本信息

  • React Native 版本:0.77.1
  • RNOH 版本:0.77.59
  • 推荐 DevEco Studio 版本:6.1.0+

反馈与支持

如果在体验过程中遇到问题:

  1. 仔细阅读"遇到问题怎么办"章节
  2. 使用 hdc shell hilog 查看详细日志
  3. 在RNOH社区寻求帮助

祝你在鸿蒙PC上的React Native开发之旅顺利!🚀

Logo

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

更多推荐