React Native for 鸿蒙0.72.5 环境搭建指南
目录
- 前置条件
- 环境变量设置
- [创建 React Native 项目](#创建 React Native 项目)
- 安装鸿蒙依赖包并生成bundle
- 创建鸿蒙工程
- 在原生工程中集成RNOH
- 加载bundle包
- 常见问题
前置条件
在开始之前,请确保您的开发环境满足以下要求:
- 操作系统: macOS 10.15+ 或 Windows 10+
- Node.js: 版本 16 或更高
- DevEco Studio: 最新版本
- OpenHarmony SDK: API 21
- React Native: 0.72.5 版本
环境变量设置
1. 配置 HDC 工具路径
打开终端,执行以下命令编辑配置文件:
bash
# 对于 zsh 用户(推荐)
open ~/.zshrc
# 对于 bash 用户
vi ~/.bash_profile
在配置文件中添加以下内容:
bash
# 添加 HDC 工具路径到 PATH(注意您的实际 SDK 安装路径)
export PATH="/Users/jianguo/Library/OpenHarmony/Sdk/20/openharmony/toolchains:$PATH"
# 设置 HDC 服务器端口
HDC_SERVER_PORT=7035
launchctl setenv HDC_SERVER_PORT $HDC_SERVER_PORT
export HDC_SERVER_PORT
注意 : HDC 端口变量名为
HDC_SERVER_PORT,变量值可设置为任意未被占用的端口,如7035。
2. 配置 CAPI 版本环境变量
当前 RN 框架提供的 Demo 工程默认为 CAPI 版本,您需要配置环境变量:
bash
export RNOH_C_API_ARCH=1
将上述命令添加到您的 shell 配置文件中(~/.bash_profile、~/.bashrc 或 ~/.zshrc)。
3. 使配置生效
编辑完成后,执行以下命令使配置的环境变量生效:
bash
# 对于 zsh 用户
source ~/.zshrc
# 对于 bash 用户
source ~/.bash_profile
4. 验证配置
重新打开终端,检查环境变量是否设置成功:
bash
echo $RNOH_C_API_ARCH
echo $HDC_SERVER_PORT
创建 React Native 项目
1. 创建新项目
使用 React Native 内置的命令行工具来创建一个新项目。目前 React Native for OpenHarmony 仅支持 0.72.5 版本的 React Native:
bash
npx react-native@0.72.5 init AwesomeDemo --version 0.72.5
2. 跳过 iOS 依赖安装(可选)
该命令在 macOS 环境下初始化 React Native 项目时会下载 iOS 依赖库,耗时较长。如果您只开发鸿蒙项目,可以选择跳过该过程:
bash
npx react-native@0.72.5 init AwesomeDemo --version 0.72.5 --skip-install
npx react-native@0.72.5 init RnDemo --version 0.72.5 --skip-install
npm i @react-native-oh/react-native-harmony@0.77.40
npx react-native@0.72.5 init AwesomeDemo --version 0.72.5 --skip-install
提示: 跳过 iOS 依赖安装不会影响鸿蒙项目的开发。
安装鸿蒙依赖包并生成bundle
版本信息
本节中使用的各类文件的版本配套关系,可以参考 React Native For OpenHarmony 版本信息。
快速开始 : 您也可以直接使用 docs/Zips/AwesomeProjectReplace 文件夹 中的对应文件进行一一替换,修改版本信息并运行。
1. 修改 package.json
打开 AwesomeDemo 目录下的 package.json,在 scripts 下新增 OpenHarmony 的依赖:
json
{
"name": "AwesomeDemo",
"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",
"dev": "react-native bundle-harmony --dev"
},
"dependencies": {
"react": "18.2.0",
"react-native": "0.72.5"
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@babel/preset-env": "^7.20.0",
"@babel/runtime": "^7.20.0",
"@react-native/eslint-config": "^0.72.2",
"@react-native/metro-config": "^0.72.11",
"@tsconfig/react-native": "^3.0.0",
"@types/react": "^18.0.24",
"@types/react-test-renderer": "^18.0.0",
"babel-jest": "^29.2.1",
"eslint": "^8.19.0",
"jest": "^29.2.1",
"metro-react-native-babel-preset": "0.76.8",
"prettier": "^2.4.1",
"react-test-renderer": "18.2.0",
"typescript": "4.8.4"
},
"engines": {
"node": ">=16"
}
}
2. 安装鸿蒙依赖包
在 AwesomeProject 目录下运行安装依赖包命令:
npm install @react-native-oh/react-native-harmony@0.72.108
注意 : 如果要使用 Codegen,请在此处配置 Codegen 相关命令,详细请参考 Codegen。
3. 配置 Metro
打开 AwesomeProject/metro.config.js,并添加 OpenHarmony 的适配代码:
javascript
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);
参考 : 配置文件的详细介绍,可以参考 React Native 中文网。
4. 生成 Bundle 文件
在 AwesomeProject 目录下运行生成 bundle 文件的命令:
bash
npm run dev
运行成功后,会在 AwesomeProject/harmony/entry/src/main/resources/rawfile 目录下生成:
bundle.harmony.js- 主要的 JavaScript bundle 文件assets文件夹 - 存放图片资源(如果 bundle 中不涉及本地图片,则没有此文件夹)
预期输出示例:
[INFO] Redirected imports from react-native to @react-native-oh/react-native-harmony
[INFO] No harmony-specific third-party packages have been detected
[CREATED] ./harmony/entry/src/main/resources/rawfile/bundle.harmony.js
info Copied 6 assets
创建鸿蒙工程
1. 创建新项目
在 DevEco Studio 中创建新的鸿蒙项目:
- 点击
File > New > Create Project - 选择创建
Empty Ability工程 - 点击
Next按钮 - 在
Compile SDK中选择API20 - 创建一个名为 "reactdemo" 的项目
- 注意项目路径不要太长


2. 配置签名
连接真机设备,配置项目签名:
- 点击
File > Project Structure - 在弹窗界面点击
Signing Configs - 勾选
Support HarmonyOS和Automatically generate signature - 点击
Sign In登录华为账号 - 完成签名配置
3.添加 React Native 配置
在 entry 目录下执行以下命令:
ohpm i @rnoh/react-native-openharmony@0.72.108
在原生工程中集成RNOH
1. 配置 CPP 侧代码
创建 cpp 目录
在 MyApplication/entry/src/main 目录下新建 cpp 文件夹。
创建 CMakeLists.txt
在 cpp 目录下新增 CMakeLists.txt,将 RNOH 的适配层代码添加到编译构建中:
cmake
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) # for other CMakeLists.txt files to use
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)
创建 PackageProvider.cpp
在 cpp 目录下新增 PackageProvider.cpp,该文件需要满足以下要求:
- 需要导入
RNOH/PackageProvider - 实现
getPackages方法,用于创建三方库或自定义 TurboModule 或 Fabric 的 package 对象
cpp
#include "RNOH/PackageProvider.h"
using namespace rnoh;
std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
return {};
}
配置 build-profile.json5
打开 MyApplication/entry/build-profile.json5,将 cpp 中的代码添加到应用工程的编译构建任务中:
json
{
"apiType": "stageMode",
"buildOption": {
"externalNativeOptions": {
"path": "./src/main/cpp/CMakeLists.txt",
"arguments": "",
"cppFlags": ""
}
},
"buildOptionSet": [
{
"name": "release",
"arkOptions": {
"obfuscation": {
"ruleOptions": {
"enable": false,
"files": [
"./obfuscation-rules.txt"
]
}
}
}
}
],
"targets": [
{
"name": "default"
},
{
"name": "ohosTest"
}
]
}
注意 : 如果在
x86_64架构的模拟器上运行应用,需在externalNativeOptions配置中额外添加abiFilters字段,并包含x86_64架构参数。默认仅构建适用于arm64-v8a架构的版本。
参考 : 详细介绍可以参考模块级build-profile.json5。
2. 配置 ArkTS 侧代码
修改 EntryAbility.ets
打开 MyApplication/entry/src/main/ets/entryability/EntryAbility.ets,引入并使用 RNAbility:
typescript
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 RNAbility {
getPagePath() {
return 'pages/Index';
}
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');
}
}
重要要求:
- 需要重写
getPagePath,返回程序的入口 page - 如果需要扩展使用对应的生命周期函数:
- 请在代码中调用
super(由于RNAbility在生命周期函数中进行了对应的操作,因此建议使用super以确保原有功能不丢失) - 需确保函数的参数列表与父类保持兼容
- 建议添加
override关键字,以提升代码可读性并增强编译器检查
- 请在代码中调用
扩展示例:
typescript
import { RNAbility } from '@rnoh/react-native-openharmony';
export default class EntryAbility extends RNAbility {
getPagePath() {
return 'pages/Index';
}
override onCreate(want: Want): void {
super.onCreate(want);
hilog.info(0x0000, 'testTag', '%{public}s', 'EntryAbility onCreate');
}
}
创建 RNPackagesFactory.ets
在 MyApplication/entry/src/main/ets 目录下新增 RNPackagesFactory.ets:
typescript
import { RNPackageContext, RNPackage } from '@rnoh/react-native-openharmony/ts';
export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
return [];
}
要求:
- 在
@rnoh/react-native-openharmony导入RNPackageContext和RNPackage - 在文件中导出
createRNPackages方法,用于创建三方库或自定义 TurboModule、Fabric 的 package 对象 - 此处不涉及三方库与自定义 TurboModule 或组件,需要返回空数组
修改 Index.ets
打开 MyApplication/entry/src/main/ets/pages/Index.ets,添加 RNOH 的使用代码:
typescript
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: "AwesomeDemo", // 尤其要注意,这个是你的rn的项目的名称
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%')
}
}
重要 :
RNApp的参数appKey需要与 RN 工程中AppRegistry.registerComponent注册的appName保持一致,否则会导致白屏。
加载bundle包
在上一章节中已经完成了 bundle 文件的生成,接下来将它加载到 DevEco Studio 中以运行 MyApplication 项目。
1. 拷贝 Bundle 文件
将 RN 侧的 rawfile 文件拷贝到鸿蒙侧的 rawfile 目录:
- 源路径:
AwesomeProject/harmony/entry/src/main/resources/rawfile/ - 目标路径:
MyApplication/entry/src/main/resources/rawfile/
2. 运行项目

连接设备
用数据线将真机与电脑连接,打开新的命令行工具并执行:
bash
hdc rport tcp:8081 tcp:8081
启动 Metro 服务器
在 RN 工程目录中执行以下命令启动 RN 应用:
bash
npm run start
预期输出:
Metro waiting on exp://192.168.x.x:8081
Scan the QR code above with Expo Go (Android) or the Camera app (iOS)
运行鸿蒙应用
在 DevEco Studio 中点击运行按钮,选择连接的设备运行应用。
相关阅读


常见问题
1. 环境变量问题
问题 : 环境变量设置后不生效
解决方案:
- 确保在正确的 shell 配置文件中添加环境变量
- 执行
source ~/.zshrc或source ~/.bash_profile使配置生效 - 重新打开终端验证环境变量
2. Bundle 生成失败
问题 : npm run dev 命令执行失败
解决方案:
- 检查 Node.js 版本是否为 16 或更高
- 确保已正确安装
@react-native-oh/react-native-harmony依赖 - 检查
metro.config.js配置是否正确
3. 应用白屏
问题 : 鸿蒙应用启动后显示白屏
解决方案:
- 检查
appKey是否与 RN 工程中的AppRegistry.registerComponent注册的appName一致 - 确保 bundle 文件已正确拷贝到鸿蒙项目的
rawfile目录 - 检查设备连接和端口转发是否正常
4. 依赖安装问题
问题 : npm 安装依赖失败或速度慢
解决方案:
- 使用国内镜像源:
npm config set registry https://repo.huaweicloud.com/repository/npm/ - 清除 npm 缓存:
npm cache clean --force - 使用 yarn 替代 npm:
yarn install
5. 编译错误
问题 : 鸿蒙项目编译失败
解决方案:
- 检查 OpenHarmony SDK 版本是否为 API 20
- 确保 DevEco Studio 版本为最新
- 检查
build-profile.json5配置是否正确 - 清理项目后重新编译:
Build > Clean Project
尤其关注这个仓库:https://atomgit.com/openharmony-sig/ohos_react_native/tree/master/docs/Zips