部署 OpenHarmony 版 React Native 开发环境

前置软件安装

先完成基础工具安装,避免后续配置受阻,所有软件建议默认路径安装(路径含中文字符易导致异常):

  1. Node.js:从官网下载 16.x 或 18.x LTS 版本,安装时勾选「Add to PATH」,安装后打开 cmd 输入 node -v 验证版本
  2. Git:官网下载最新版,默认配置即可,安装后通过 git --version 验证
  3. Visual Studio Code:官网下载,安装后推荐安装 React Native Tools、ArkTS 相关插件
  4. DevEco Studio:从华为开发者联盟下载,安装时选择「OpenHarmony 开发」选项,启动后按提示下载 API 20+ 的 OpenHarmony SDK(含 toolchains 工具集)

确保系统满足以下要求:Windows 10 或更高版本,Node.js 版本 16 或更高,Java Development Kit (JDK) 版本 8 或更高。安装 Git 并配置环境变量。

详细安装过程不加赘述,其他文章均有介绍。

 1:配置 hdc 环境变量

环境搭建常见问题及解决方案

依赖项冲突或缺失
开源鸿蒙开发环境需配置Python、Node.js等工具链,版本不匹配易导致编译失败。建议使用DevEco Studio官方推荐版本,并通过hpm check命令验证环境完整性。若出现"No matching distribution found"错误,需检查pip源或手动下载whl文件安装。

SDK下载缓慢或失败
国内开发者可通过华为镜像站加速下载。修改ohpm/ohpmrc配置文件,替换为国内镜像URL。若出现证书验证错误,添加--insecure参数临时绕过或更新系统根证书。

模拟器无法启动
检查BIOS中是否开启VT-x虚拟化支持,Linux系统需加载kvm模块。若模拟器黑屏,尝试切换OpenGL渲染模式为Software,或更新显卡驱动至最新版本。

跨平台应用运行异常处理

资源适配异常
开源鸿蒙的屏幕碎片化程度高,需在config.json中声明多分辨率资源。出现布局错乱时,使用百分比布局替代固定像素值,并通过ohos.system.deviceAPI动态获取屏幕参数。

Native库兼容性问题
ARM架构设备运行x86编译的so文件会触发SIGILL错误。需在CMake中配置多ABI编译:

set(nativeLibSrc_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/main/cpp)  
add_library(native-lib SHARED ${nativeLibSrc_DIR}/native-lib.cpp)  
target_compile_options(native-lib PRIVATE -march=armv8-a)  

线程阻塞导致ANR
鸿蒙应用主线程禁止网络请求。使用TaskDispatcher异步任务机制,对于耗时操作需显式声明:

let taskGroup = taskpool.TaskGroup();  
taskGroup.addTask(() => ImageProcessor.applyFilter(rawData));  
taskpool.execute(taskGroup).then((result) => { /* 更新UI */ });  

调试技巧与日志分析

HiLog日志过滤
通过hilog -D -T MyTag命令实时查看指定模块日志。若日志不输出,检查/etc/init/logctl.conf中是否配置了对应模块的日志级别。

性能问题定位
使用SmartPerf工具捕捉帧率下降场景,重点关注/proc/meminfoPageFaults指标突增。对于内存泄漏,通过dumpheap生成hprof文件后,使用Eclipse MAT分析对象引用链。

分布式调试难点
跨设备调用需确保同一超级终端组网。若出现ERR_DISTRIBUTED_SCHEDULE_FAILED,验证设备间udid绑定状态,并检查distributedHardwareConfig.json中的权限声明是否完整。

安装 DevEco Studio

下载并安装 DevEco Studio,这是 OpenHarmony 官方开发工具。安装过程中选择 OpenHarmony 开发环境。安装完成后,启动 DevEco Studio 并配置 SDK。

找到 hdc 工具路径

hdc 工具位于 OpenHarmony SDK 的 toolchains 目录下

  1. 打开 DevEco Studio
  2. “文件” → “设置” → “OpenHarmony SDK”

在该页面中确认直接相应的toolchains 已经下载,如果出现未下载的情况即可勾选应用就会自动下载该组件。

接下来根据该目录找到相应版本位置复制toolchains 的根目录。在设置中的系统中找到高级系统设置,选择环境变量。在系统变量中找到Path,进入编辑,将刚才复制的根目录路径复制进去:

2. 配置 HDC_SERVER_PORT 环境变量

为 hdc 工具配置连接端口:

  1. 在「系统变量」区域点击「新建」
  2. 变量名:HDC_SERVER_PORT,变量值:7035(或其他未被占用的端口)
  3. 点击「确定」保存

3. 配置 CAPI 版本环境变量

启用当前推荐的 CAPI(Component API)架构:

  1. 在「系统变量」区域点击「新建」
  2. 变量名:RNOH_C_API_ARCH,变量值:1
  3. 点击「确定」保存

接下来即可验证hdc环境

执行 hdc version,若显示版本信息,则 hdc 配置成功

2:工程创建与关联

2.1 创建 React Native 基础工程

注意:当前 React Native for OpenHarmony 仅兼容 0.72.5 版本,需指定版本创建:

  1. 选择工程目录:打开文件资源管理器,进入拟存放项目的目录(如 D:\OHProjects),右键选择「在终端中打开」或者直接在该目录的位置输入cmd

  1. 执行创建命令:在终端输入以下命令(将 OHRN_Demo 改为自定义项目名):
npx react-native@0.72.5 init AtomGitNews --version 0.72.5
  1. 等待完成:首次创建会自动下载依赖,耗时 5-15 分钟(取决于网络),若依赖安装失败,进入项目目录执行 npm install 重试

2.2 创建 OpenHarmony 载体工程

OpenHarmony 工程将作为 React Native 代码的运行载体,需放在 RN 工程的 harmony 子目录下:

  1. 启动 DevEco Studio:欢迎界面点击「Create Project」
  2. 选择模板:在模板列表中找到「Empty Ability」,点击「Next」

  1. 配置工程信息:
  • Project Name:自定义(如 OHRN_Demo_Harmony)
  • Package Name:默认即可(如 com.example.ohrndemo)
  • Save Location:必须选择上述 RN 工程根目录下的 harmony 子目录(示例:D:\OHProjects\OHRN_Demo\harmony)
  • Minimum API Level:选择 20 或更高
  • Device Type:勾选「Phone」

  1. 点击「Finish」:DevEco Studio 会自动创建工程并同步基础依赖

3:依赖安装与打包配置

3.1 安装 OpenHarmony 适配依赖

进入 RN 工程目录,安装 React Native 与 OpenHarmony 的适配依赖:

  1. 进入项目目录:在终端中输入 cd OHRN_Demo(切换到 RN 工程根目录)
  2. 安装依赖:执行以下命令(版本需与 RN 版本匹配):npm i @react-native-oh/react-native-harmony@0.72.90
  3. 等待完成:安装成功后,终端无报错信息

3.2 配置 Metro 打包工具

Metro 是 React Native 的默认打包工具,需修改配置适配 OpenHarmony:

  • 打开配置文件:用 VS Code 打开 RN 工程根目录的 metro.config.js 文件
  • 替换配置内容:删除原有内容,粘贴以下配置:
const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
const {createHarmonyMetroConfig} = require("@react-native-oh/react-native-harmony/metro.config");

/**
 * Metro configuration
 * https://facebook.github.io/metro/docs/configuration
 *
 * @type {import('metro-config').MetroConfig}
 */
const config = {
    transformer: {
        getTransformOptions: async () => ({
            transform: {
                experimentalImportSupport: false,
                inlineRequires: true
            }
        })
    }
};

module.exports = mergeConfig(getDefaultConfig(__dirname), createHarmonyMetroConfig({
    reactNativeHarmonyPackageName: '@react-native-oh/react-native-harmony'
}), config);
  1. 生成 Bundle:在 RN 工程根目录的终端中,输入 npm run harmony,等待打包完成
  2. 验证结果:打包成功后,会在 harmony/entry/src/main/resources/rawfile/ 目录下生成 bundle.harmony.js(核心脚本)和 assets(资源文件夹)

4:OpenHarmony 工程集成配置

4.1 安装 OpenHarmony 端依赖

在 DevEco Studio 中,为 OpenHarmony 工程安装 RN 适配依赖:

  1. 打开终端:在 DevEco Studio 中,右键点击「entry」目录,选择「Open In → Terminal」
  2. 执行安装命令:输入以下命令(版本需与 @react-native-oh/react-native-harmony 一致):ohpm i @rnoh/react-native-openharmony@0.72.90

  1. 同步工程:安装完成后,点击 DevEco Studio 右上角的「Sync Now」,同步依赖配置

4.2 CPP 侧配置(核心适配)

需添加 CPP 相关配置,确保 RN 代码与 OpenHarmony 原生层通信:

4.2.1 创建 cpp 目录及 CMakeLists.txt

  1. 创建目录:在 DevEco Studio 中,展开 entry → src → main,右键 main 目录,选择「New → Directory」,命名为 cpp
  2. 创建 CMakeLists.txt:右键 cpp 目录,选择「New → File」,命名为 CMakeLists.txt,粘贴以下内容:

4.2.2 创建 PackageProvider.cpp

新建文件:右键 cpp 目录,选择「New → C/C++ Source File」,命名为 PackageProvider.cpp

添加内容:粘贴以下代码(暂不涉及三方插件,返回空列表):#include "RNOH/PackageProvider.h"using namespace rnoh;

  1. 打开文件:展开 entry 目录,找到 build-profile.json5 并打开
  2. 添加 abiFilters:在 externalNativeOptions 节点中添加 "abiFilters": ["arm64-v8a", "x86_64"],最终配置如下:"externalNativeOptions": {"path": "./src/main/cpp/CMakeLists.txt","arguments": "","cppFlags": "","abiFilters": ["arm64-v8a", "x86_64"] // 新增,支持模拟器和真机}
  3. 同步配置:点击「Sync Now」
  4. 打开文件:展开 entry → src → main → ets → entryability,打开 EntryAbility.ets
  5. 替换代码:删除原有内容,粘贴以下代码(继承 RNAbility 实现适配):

4.2.3 配置 build-profile.json5

  1. 打开文件:展开 entry 目录,找到 build-profile.json5 并打开
  2. 添加 abiFilters:在 externalNativeOptions 节点中添加 "abiFilters": ["arm64-v8a", "x86_64"],最终配置如下:"externalNativeOptions": {"path": "./src/main/cpp/CMakeLists.txt","arguments": "","cppFlags": "","abiFilters": ["arm64-v8a", "x86_64"] // 新增,支持模拟器和真机}
  3. 同步配置:点击「Sync Now」

4.3 ArkTS 侧代码适配

4.3.1 修改 EntryAbility.ets

  1. 打开文件:展开 entry → src → main → ets → entryability,打开 EntryAbility.ets
  2. 替换代码:删除原有内容,粘贴以下代码(继承 RNAbility 实现适配):
  3. import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit';
    import { hilog } from '@kit.PerformanceAnalysisKit';
    import { window } from '@kit.ArkUI';
    import { RNAbility } from '@rnoh/react-native-openharmony';
    
    
    const DOMAIN = 0x0000;
    
    export default class EntryAbility extends UIAbility {
      protected getPagePath(): string {
        return "pages/Index"
      }
      onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
        super.onCreate(want, launchParam);
        try {
          this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
        } catch (err) {
          hilog.error(DOMAIN, 'testTag', 'Failed to set colorMode. Cause: %{public}s', JSON.stringify(err));
        }
        hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
      }
    
      onDestroy(): void {
        hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy');
      }
    
      onWindowStageCreate(windowStage: window.WindowStage): void {
        // Main window is created, set main page for this ability
        hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
    
        windowStage.loadContent('pages/Index', (err) => {
          if (err.code) {
            hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
            return;
          }
          hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
        });
      }
    
      onWindowStageDestroy(): void {
        // Main window is destroyed, release UI related resources
        hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
      }
    
      onForeground(): void {
        // Ability has brought to foreground
        hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground');
      }
    
      onBackground(): void {
        // Ability has back to background
        hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground');
      }
    }

    并修改index.ets:

  4. 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 {
        // NOTE: this is required since `Ability`'s `onBackPressed` function always
        // terminates or puts the app in the background, but we want Ark to ignore it completely
        // when handled by 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: "AtomGitNews",
              wrappedCustomRNComponentBuilder: wrappedCustomRNComponentBuilder,
              onSetUp: (rnInstance) => {
                rnInstance.enableFeatureFlag("ENABLE_RN_INSTANCE_CLEAN_UP")
              },
              jsBundleProvider: new TraceJSBundleProviderDecorator(
                new AnyJSBundleProvider([
                  new MetroJSBundleProvider(),
                  // NOTE: to load the bundle from file, place it in
                  // `/data/app/el2/100/base/com.rnoh.tester/files/bundle.harmony.js`
                  // on your device. The path mismatch is due to app sandboxing on OpenHarmony
                  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%')
      }
    }
    

5:模拟器运行与验证

5.1 配置 OpenHarmony 模拟器

  1. 打开设备管理:在 DevEco Studio 工具栏,点击「No Devices」下拉框,选择「Device Manager」
  2. 创建模拟器:
  • 点击「New Emulator」,选择「Huawei_Phone」模板,点击「Next」
  • 选择 API 20+ 的镜像(推荐 HarmonyOS 6.0 版本),点击「Download」下载(约 1-2GB,耗时 10-30 分钟)
  • 下载完成后,点击「Finish」完成模拟器创建
  1. 启动模拟器:在设备列表中,点击模拟器右侧的「运行」按钮,首次启动需 1-2 分钟

5.2 运行应用

  1. 确认设备连接:DevEco Studio 工具栏会显示模拟器名称(如「Huawei_Phone_6.0」),说明连接成功
  2. 启动运行:点击工具栏的绿色「运行」按钮(或按 Shift+F10),DevEco Studio 会自动编译、安装应用
  3. 验证结果:编译完成后,模拟器会自动打开应用,显示 React Native 经典的「Welcome to React Native」界面,说明部署成功

遇到的相关问题排查:

  • 关键验证点:执行ohpm命令后无「未找到命令」提示,且能成功安装@rnoh/react-native-openharmony依赖;
  • 避坑提醒:ohpm命令仅在 OpenHarmony 工程目录下执行有效,不要在 RN 工程根目录执行。

结语

希望这篇文章能对正在尝试鸿蒙跨平台开发的同学有所帮助,也欢迎大家在评论区交流踩坑经验。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

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

更多推荐