如何在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下载

相关推荐
2501_9159090619 小时前
深入解析Mock.js:功能、应用及实战案例,提升前端开发效率
android·ios·小程序·https·uni-app·iphone·webview
nashane19 小时前
HarmonyOS 6学习:NFC服务中IsoDep连接失败的排查与解决——从参数匹配到多SDK协同的完整指南
学习·华为·harmonyos
坚果派·白晓明20 小时前
[鸿蒙PC三方库移植适配] 使用 AtomCode + Skills 自动完成11Zip鸿蒙化适配
harmonyos·鸿蒙·c/c++三方库
李二。21 小时前
鸿蒙原生密码保险箱 PasswordVault 应用开发实战
华为·harmonyos
科技与数码21 小时前
鸿蒙AI防诈能力:场景化防诈+换脸检测+亲情防诈
人工智能·华为·harmonyos
小菜鸟学开发21 小时前
OpenHarmony v6.1-release 编译指南
harmonyos
pop_xiaoli21 小时前
【iOS】通知传值实现
macos·ios·xcode
2601_9557674221 小时前
iPhone 17 屏幕偏振光学解析与保护贴技术选择——悟赫德观复盾护景贴
人工智能·科技·ios·ar·iphone·圆偏振光
李二。1 天前
鸿蒙 HarmonyOS 待办清单应用开发实战 —— 基于 ArkTS + SQLite 的完整教程
华为·sqlite·harmonyos
Pocker_Spades_A1 天前
[鸿蒙PC命令行移植适配]移植rust三方库peep到鸿蒙PC的完整实践
华为·rust·harmonyos