开源鸿蒙-React编译开发
后来我查看了GitCode的版本说明,忘记查看了自己的DevEco Studio版本(记得查看自己的DevEco Studio版本),就去问AI了,然后AI叫我去下了个0.76.8的版本,结果就是失败了。然后执行"npm i @react-native-oh/react-native-harmony@x.x.x",这里最好指定一下版本,比如我的DevEco Studio是6.0.0版本,React
一、记录踩到的坑
参考的是这篇文章,但是踩了好多坑,这里逐一列举出来。ohos_react_native/docs/zh-cn/版本说明.md · OpenHarmony-SIG/ohos_react_native - GitCode
https://gitcode.com/openharmony-sig/ohos_react_native/blob/master/docs/zh-cn/%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA.md?mode=light
1.1 .npmrc文件存在多个
文章说编辑用户级.npmrc配置文件,但是Everything搜索.npmrc,发现有很多个,但是我没有 C:\Users\用户名\.npmrc这个路径的文件。这里我选择了DevEco Studio目录下的.npmrc文件。



1.2 React与HarmonyOS版本不兼容
根据文章执行"npm i @react-native-oh/react-native-harmony@x.x.x"命令。如果@x.x.x没进行指定,默认下载最新版本。于是我就没指定版本直接执行了,下载了v0.76.9的版本。但是在 React Native 0.72+ 版本中,DrawerLayoutAndroid 组件已经被移除了,但 HarmonyOS 插件还在尝试引用这个已经不存在的模块,所以后面就一堆爆红了。后来我查看了GitCode的版本说明,忘记查看了自己的DevEco Studio版本(记得查看自己的DevEco Studio版本),就去问AI了,然后AI叫我去下了个0.76.8的版本,结果就是失败了。这时候查看GitCode的版本说明,最新版本仅支持0.72.101,AI叫我下的版本远超这个版本了。根据官方文档,要下载的是0.72.71,建议一开始就指定适合自己的版本,不然可能会有坑。选择0.72.71版本后,很快就成功了。
ohos_react_native/docs/zh-cn/版本说明.md · OpenHarmony-SIG/ohos_react_native - GitCode
npm i @react-native-oh/react-native-harmony@x.x.x







1.3 忘记把文件拷贝进来
忘记把文件拷贝进来,导致编译错误。执行完"npx react-native@0.72.5 init AwesomeProject --version 0.72.5 --skip-install"命令后,会生成一个AwesomeProject的文件。里面有两个文件:bundle.harmony.js文件和assets文件夹。(注意assets文件夹有两个,选择里面有三个文件那个),然后拷贝进去鸿蒙的rawfile文件夹下。
npx react-native@0.72.5 init AwesomeProject --version 0.72.5 --skip-install





二、React鸿蒙环境搭建
开发环境搭建这里就不讲了,具体可以参考幻影的鸿蒙开发之旅1-安装DevStudio-CSDN博客
2.1 新建系统变量
打开系统环境变量,选择Path点击编辑,分别在里面新建两个变量:
toolchains的路径:"D:\All_ide\HongMeng\ide\OpenHarmony_SDK\20\toolchains"
"HDC_SERVER_PORT":7035



2.2 配置鸿蒙项目
执行"npx react-native@0.72.5 init AwesomeProject --version 0.72.5 --skip-install"会得到一个文件:AwesomeProject


下载并安装鸿蒙化依赖
打开 AwesomeProject 目录下的 package.json,在 scripts 下新增 OpenHarmony 的依赖:
,"dev": "react-native bundle-harmony --dev"1r
{
"name": "AwesomeProject",
"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"
}
}
然后执行"npm i @react-native-oh/react-native-harmony@x.x.x",这里最好指定一下版本,比如我的DevEco Studio是6.0.0版本,React下载的版本最好是0.72.71的。所以命令可以改为"npm i @react-native-oh/react-native-harmony@0.72.71"


运行指令并生成bundle
打开 AwsomeProject\metro.config.js,并添加 OpenHarmony 的适配代码。配置文件的详细介绍,可以参考React Native 中文网。修改完成后的文件内容如下:
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);
新建一个鸿蒙项目
具体怎么新建就不说了,网上很多教程。这里我们讲需要配置哪些文件。
1.在src文件夹中的main目录新建一个cpp文件夹,分别存放CMakeLists.txt和PackageProvider.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) # 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文件内容如下:
#include "RNOH/PackageProvider.h"
using namespace rnoh;
std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
return {};
}
2.打开 MyApplicaton\entry\build-profile.json5,将 cpp 中的代码添加到应用工程的编译构建任务中
build-profile.json5文件内容如下:
{
"apiType": "stageMode",
"buildOption": {
"externalNativeOptions": {
"path": "./src/main/cpp/CMakeLists.txt",
"arguments": "",
"cppFlags": "",
"abiFilters": ["arm64-v8a", "x86_64"]
},
"resOptions": {
"copyCodeResource": {
"enable": false
}
}
},
"buildOptionSet": [
{
"name": "release",
"arkOptions": {
"obfuscation": {
"ruleOptions": {
"enable": false,
"files": [
"./obfuscation-rules.txt"
]
}
}
}
},
],
"targets": [
{
"name": "default"
},
{
"name": "ohosTest",
}
]
}

3.补充ArkTS侧的代码
EntryAbility.ets文件内容如下:
import { RNAbility } from '@rnoh/react-native-openharmony';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
const DOMAIN = 0x0000;
export default class EntryAbility extends RNAbility {
getPagePath() {
return 'pages/Index';
}
override onCreate(want: Want): void {
super.onCreate(want);
hilog.info(DOMAIN, 'testTag', '%{public}s', 'EntryAbility onCreate');
}
override onDestroy(): void {
super.onDestroy();
hilog.info(DOMAIN, 'testTag', '%{public}s', 'EntryAbility onDestroy');
}
override onWindowStageCreate(windowStage: window.WindowStage): void {
super.onWindowStageCreate(windowStage);
hilog.info(DOMAIN, 'testTag', '%{public}s', 'EntryAbility onWindowStageCreate');
}
override onWindowStageDestroy(): void {
super.onWindowStageDestroy();
hilog.info(DOMAIN, 'testTag', '%{public}s', 'EntryAbility onWindowStageDestroy');
}
override onForeground(): void {
super.onForeground();
hilog.info(DOMAIN, 'testTag', '%{public}s', 'EntryAbility onForeground');
}
override onBackground(): void {
super.onBackground();
hilog.info(DOMAIN, 'testTag', '%{public}s', 'EntryAbility onBackground');
}
}

4.在 MyApplicaton\entry\src\main\ets 目录下新增 RNPackagesFactory.ets,该文件需要满足以下要求:
- 在
@rnoh/react-native-openharmony导入RNPackageContext和RNPackage; - 在文件中导出
createRNPackages方法,用于创建三方库或自定义 TurboModule、Fabric的package 对象。

5.打开 MyApplicaton\entry\src\main\ets\pages\Index.ets,添加RNOH的使用代码,修改后如下:
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: "AwesomeProject",
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%')
}
}

加载bundle包
参考这篇文章,里面提供了三个方式,我们使用的是方式一。
AwesomeProject的文件。里面有两个文件:bundle.harmony.js文件和assets文件夹。(注意assets文件夹有两个,选择里面有三个文件那个),然后拷贝进去鸿蒙的rawfile文件夹下。





至此,所有需要配置的文件配置完毕。
三、运行自己的第一个项目
点击绿色右三角,运行自己的模拟器。成功运行,完结撒花!!!~~


更多推荐


所有评论(0)