如何在Mac搭建鸿蒙的ReactNative 开发环境

1. 增加环境变量

打开或者创建~/.zshrc文件,在文件的末尾增加下面环境变量,然后执行 source ~/.zshrc

ini 复制代码
export PATH="/Applications/DevEco-Studio.app/Contents/sdk/default/openharmony/toolchains:$PATH" # 按照实际 SDK 安装路径配置,需要选择{显示包内容}
HDC_SERVER_PORT=7035 
launchctl setenv HDC_SERVER_PORT $HDC_SERVER_PORT 
export HDC_SERVER_PORT
export RNOH_C_API_ARCH=1

2. 创建 ReactNative 新项目

kotlin 复制代码
npx react-native@0.72.5 init TestHarmonyRN --version 0.72.5 --npm

添加---npm是为了避免下面这个错误出现

error Couldn't find the "/var/folders/d3/nhr1qyk17xzgj7wh11yxvyhc0000gn/T/rncli-init-template-DAyOpL/node_modules/react-native/template.config.js file inside "react-native" template. Please make sure the template is valid.

3. 修改ReactNative项目

  1. 安装鸿蒙依赖

    在TestHarmonyRN目录下执行npm i @react-native-oh/react-native-harmony

  2. 修改metro(metro.config.js)配置

javascript 复制代码
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
);

4. 创建并修改鸿蒙原生工程

1. 安装ReactNative依赖在entry目录下执行

css 复制代码
ohpm i @rnoh/react-native-openharmony

执行完成后,在entry目录下会生成oh_modules文件夹

2. 修改原生代码支持RN

1. 在entry/src/main目录下面新建cpp文件夹
2. 在cpp目录下新增CMakeLists.txt文件
scss 复制代码
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)
3. 在cpp目录下新增PackageProvider.cpp文件
arduino 复制代码
#include "RNOH/PackageProvider.h"

using namespace rnoh;

std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
    return {};
}
4. 修改entry\build-profile.json5里的buildOption
json 复制代码
"buildOption": {
    "externalNativeOptions": {
      "path": "./src/main/cpp/CMakeLists.txt",
      "arguments": "",
      "cppFlags": "",
    }
  }
5. 修改entry/src/main/ets/entryability/EntryAbility.ets
scala 复制代码
import { RNAbility } from '@rnoh/react-native-openharmony';

export default class EntryAbility extends RNAbility {
  getPagePath() {
    return 'pages/Index';
  }
}
6. 在entry/src/main/ets新增RNPackagesFactory.ets
javascript 复制代码
import { RNPackageContext, RNPackage } from '@rnoh/react-native-openharmony/ts';
export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
  return [];
}
7. 修改 entry/src/main/ets/pages/Index.ets文件
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: "TestHarmonyRN",
          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%')
  }
}
8. 配置摇一摇权限,修改module.json5
json 复制代码
"requestPermissions": [
    {
        "name": "ohos.permission.ACCELEROMETER"
    }
],

5.调试并运行

1. 启动ReactNative项目

在ReactNative项目目录下执行npm run start

2. 启动鸿蒙项目,并摇一摇,输入自己本地的ip地址+8081的,模拟器摇一摇如图

6.demo下载

demo下载

相关推荐
朝阳392 小时前
ReactNative【实战】瀑布流布局列表(含图片自适应、点亮红心动画)
react native
YungFan4 小时前
iOS26适配指南之UINavigationController
ios·swift
请叫我小蜜蜂同学5 小时前
【鸿蒙】鸿蒙操作系统发展综述
华为·harmonyos
木叶丸6 小时前
Flutter 生命周期完全指南
android·flutter·ios
HMS Core6 小时前
借助HarmonyOS SDK,《NBA巅峰对决》实现“分钟级启动”到“秒级进场”
华为·harmonyos
塞尔维亚大汉9 小时前
鸿蒙内核源码分析(文件句柄篇) | 你为什么叫句柄?
源码·harmonyos
别说我什么都不会9 小时前
【OpenHarmony】鸿蒙开发之FlexSearch
harmonyos
Keya9 小时前
解决 pod install 警告信息显示不完全的方法
ios·xcode·cocoapods
HarmonyOS小助手10 小时前
在鸿蒙中造梦的开发者,一边回答,一边前行
harmonyos·鸿蒙·harmonyos next·鸿蒙生态
随笔记11 小时前
uniapp开发的小程序输入框在ios自动填充密码,如何欺骗苹果手机不让自动填充
前端·ios·app