[React Native for OpenHarmony]在Windows 环境下部署 OpenHarmony版React Native开发环境
本文详细介绍了OpenHarmony版ReactNative开发环境的部署流程。首先需要安装Node.js、Git、VSCode和DevEcoStudio等基础工具,并配置hdc环境变量。接着创建ReactNative基础工程(仅兼容0.72.5版本)和OpenHarmony载体工程,安装必要的适配依赖并配置Metro打包工具。最后进行OpenHarmony工程集成配置,包括CPP侧配置和ArkT
部署 OpenHarmony 版 React Native 开发环境
前置软件安装
先完成基础工具安装,避免后续配置受阻,所有软件建议默认路径安装(路径含中文字符易导致异常):
- Node.js:从官网下载 16.x 或 18.x LTS 版本,安装时勾选「Add to PATH」,安装后打开 cmd 输入 node -v 验证版本
- Git:官网下载最新版,默认配置即可,安装后通过 git --version 验证
- Visual Studio Code:官网下载,安装后推荐安装 React Native Tools、ArkTS 相关插件
- 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/meminfo的PageFaults指标突增。对于内存泄漏,通过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 目录下
- 打开 DevEco Studio
- “文件” → “设置” → “OpenHarmony SDK”

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

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

2. 配置 HDC_SERVER_PORT 环境变量
为 hdc 工具配置连接端口:
- 在「系统变量」区域点击「新建」
- 变量名:
HDC_SERVER_PORT,变量值:7035(或其他未被占用的端口) - 点击「确定」保存

3. 配置 CAPI 版本环境变量
启用当前推荐的 CAPI(Component API)架构:
- 在「系统变量」区域点击「新建」
- 变量名:
RNOH_C_API_ARCH,变量值:1 - 点击「确定」保存

接下来即可验证hdc环境
执行 hdc version,若显示版本信息,则 hdc 配置成功

2:工程创建与关联
2.1 创建 React Native 基础工程
注意:当前 React Native for OpenHarmony 仅兼容 0.72.5 版本,需指定版本创建:
- 选择工程目录:打开文件资源管理器,进入拟存放项目的目录(如 D:\OHProjects),右键选择「在终端中打开」或者直接在该目录的位置输入cmd

- 执行创建命令:在终端输入以下命令(将 OHRN_Demo 改为自定义项目名):
npx react-native@0.72.5 init AtomGitNews --version 0.72.5

- 等待完成:首次创建会自动下载依赖,耗时 5-15 分钟(取决于网络),若依赖安装失败,进入项目目录执行 npm install 重试

2.2 创建 OpenHarmony 载体工程
OpenHarmony 工程将作为 React Native 代码的运行载体,需放在 RN 工程的 harmony 子目录下:
- 启动 DevEco Studio:欢迎界面点击「Create Project」
- 选择模板:在模板列表中找到「Empty Ability」,点击「Next」

- 配置工程信息:
- 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」

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

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

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

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);
- 生成 Bundle:在 RN 工程根目录的终端中,输入 npm run harmony,等待打包完成
- 验证结果:打包成功后,会在 harmony/entry/src/main/resources/rawfile/ 目录下生成 bundle.harmony.js(核心脚本)和 assets(资源文件夹)

4:OpenHarmony 工程集成配置
4.1 安装 OpenHarmony 端依赖
在 DevEco Studio 中,为 OpenHarmony 工程安装 RN 适配依赖:
- 打开终端:在 DevEco Studio 中,右键点击「entry」目录,选择「Open In → Terminal」
- 执行安装命令:输入以下命令(版本需与 @react-native-oh/react-native-harmony 一致):ohpm i @rnoh/react-native-openharmony@0.72.90

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

4.2 CPP 侧配置(核心适配)
需添加 CPP 相关配置,确保 RN 代码与 OpenHarmony 原生层通信:
4.2.1 创建 cpp 目录及 CMakeLists.txt
- 创建目录:在 DevEco Studio 中,展开 entry → src → main,右键 main 目录,选择「New → Directory」,命名为 cpp
- 创建 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;
- 打开文件:展开 entry 目录,找到 build-profile.json5 并打开
- 添加 abiFilters:在 externalNativeOptions 节点中添加 "abiFilters": ["arm64-v8a", "x86_64"],最终配置如下:"externalNativeOptions": {"path": "./src/main/cpp/CMakeLists.txt","arguments": "","cppFlags": "","abiFilters": ["arm64-v8a", "x86_64"] // 新增,支持模拟器和真机}
- 同步配置:点击「Sync Now」
- 打开文件:展开 entry → src → main → ets → entryability,打开 EntryAbility.ets
- 替换代码:删除原有内容,粘贴以下代码(继承 RNAbility 实现适配):
4.2.3 配置 build-profile.json5
- 打开文件:展开 entry 目录,找到 build-profile.json5 并打开
- 添加 abiFilters:在 externalNativeOptions 节点中添加 "abiFilters": ["arm64-v8a", "x86_64"],最终配置如下:"externalNativeOptions": {"path": "./src/main/cpp/CMakeLists.txt","arguments": "","cppFlags": "","abiFilters": ["arm64-v8a", "x86_64"] // 新增,支持模拟器和真机}
- 同步配置:点击「Sync Now」
4.3 ArkTS 侧代码适配
4.3.1 修改 EntryAbility.ets
- 打开文件:展开 entry → src → main → ets → entryability,打开 EntryAbility.ets
- 替换代码:删除原有内容,粘贴以下代码(继承 RNAbility 实现适配):
-
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:
-
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 模拟器
- 打开设备管理:在 DevEco Studio 工具栏,点击「No Devices」下拉框,选择「Device Manager」
- 创建模拟器:
- 点击「New Emulator」,选择「Huawei_Phone」模板,点击「Next」
- 选择 API 20+ 的镜像(推荐 HarmonyOS 6.0 版本),点击「Download」下载(约 1-2GB,耗时 10-30 分钟)
- 下载完成后,点击「Finish」完成模拟器创建
- 启动模拟器:在设备列表中,点击模拟器右侧的「运行」按钮,首次启动需 1-2 分钟
5.2 运行应用
- 确认设备连接:DevEco Studio 工具栏会显示模拟器名称(如「Huawei_Phone_6.0」),说明连接成功

- 启动运行:点击工具栏的绿色「运行」按钮(或按 Shift+F10),DevEco Studio 会自动编译、安装应用
- 验证结果:编译完成后,模拟器会自动打开应用,显示 React Native 经典的「Welcome to React Native」界面,说明部署成功

遇到的相关问题排查:
- 关键验证点:执行
ohpm命令后无「未找到命令」提示,且能成功安装@rnoh/react-native-openharmony依赖; - 避坑提醒:
ohpm命令仅在 OpenHarmony 工程目录下执行有效,不要在 RN 工程根目录执行。
结语
希望这篇文章能对正在尝试鸿蒙跨平台开发的同学有所帮助,也欢迎大家在评论区交流踩坑经验。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐


所有评论(0)