如何在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 [email protected] 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下载

相关推荐
小脑斧爱吃鱼鱼28 分钟前
鸿蒙项目笔记(1)
笔记·学习·harmonyos
鸿蒙布道师1 小时前
鸿蒙NEXT开发对象工具类(TS)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
zhang1062091 小时前
HarmonyOS 基础组件和基础布局的介绍
harmonyos·基础组件·基础布局
马剑威(威哥爱编程)2 小时前
在HarmonyOS NEXT 开发中,如何指定一个号码,拉起系统拨号页面
华为·harmonyos·arkts
刘小哈哈哈3 小时前
封装了一个iOS多分区自适应宽度layout
macos·ios·cocoa
GeniuswongAir3 小时前
Flutter极速接入IM聊天功能并支持鸿蒙
flutter·华为·harmonyos
90后的晨仔6 小时前
鸿蒙ArkUI框架中的状态管理
harmonyos
布多7 小时前
Tagged Pointer:苹果工程师的内存优化艺术
ios·源码
Rudon滨海渔村9 小时前
新旧iPhone相册复制 - 相册图片视频对拷 - 换机 - 迁移设备数据 - 免费开源爱思助手
ios·iphone
别说我什么都不会1 天前
OpenHarmony 5.0(API 12)关系型数据库relationalStore 新增本地数据变化监听接口介绍
api·harmonyos