news 2026/10/14 2:08:53

RNOH Autolinking 实践指南:从三方件打包到 HarmonyOS 自动链接全流程解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
RNOH Autolinking 实践指南:从三方件打包到 HarmonyOS 自动链接全流程解析
  • OpenHarmony
  • 移动开发
  • 跨平台

【免费下载链接】ohos_react_native

React Native鸿蒙化仓库

项目地址:https://gitcode.com/CPF-RN/ohos_react_native
点击查看免费下载

本文基于 ohos_react_native 仓库中的 AutolinkingSample 示例工程,系统讲解 React Native 鸿蒙化(RNOH)生态下**三方库自动链接(Autolinking)**的完整落地路径:从编写 RN 三方件(TurboModule / Fabric 组件)、pnpm pack打包、ReactProject 侧接入与 bundle 生成,到 NativeProject(Harmony 工程)通过link-harmony自动生成 ETS/C++ 链接代码并完成编译运行。读完本文,你将掌握如何把自研三方库以极低人工成本接入 RNOH 工程,并理解自动链接背后"扫描 HAR → 生成 Package 工厂 → 更新 oh-package 依赖 → CMake 自动链接"的底层机制。

AutolinkingSample 运行效果

一、示例工程总览

AutolinkingSample 是 RNOH Autolinking 的演示工程,位于 docs/Samples/AutolinkingSample,其目录结构如下:

AutolinkingSample ├── NativeProject # Harmony(OpenHarmony)原生工程 ├── react-native-oh # RNOH 前端及脚手架 ├── ReactProject # React Native 前端工程 ├── screenshots # 运行效果图 ├── third-party-library-sample # RN 三方件示例(待接入的自研库) └── README.md / README_zh.md # 中英文说明

整个示例演示了一条完整的"三方件自研 → 自动链接"链路:

  • third-party-library-sample:一个"待发布的 RN 三方库",内部同时包含三种典型原生能力——ETS 实现的 UI 组件(SelectBox)、C++ 实现的 Fabric 组件(QDGestureFloat)、两个 TurboModule(SampleTurboModule与SampleAnyThreadTurboModule);
  • ReactProject:普通 RN 前端工程,通过file:方式依赖本地打包出的三方件,并调用其导出能力;
  • NativeProject:Harmony 原生壳工程,在编译期自动完成对三方件 HAR(Harmony Archive)与原生代码的链接。

二、环境搭建与运行(五步走)

按照 README_zh.md 的流程,依次执行:

1. 打包三方件:pnpm pack

进入third-party-library-sample目录执行:

pnpm pack

该命令基于 third-party-library-sample/package.json 中的files字段(index.ts、src/*、harmony/*)将三方件打成third-party-library-sample-1.0.0.tgz压缩包,供 RN 工程以本地包形式安装。

2. 安装依赖并生成 bundle

在ReactProject目录下依次执行:

pnpm i # 安装依赖 pnpm dev # 打包生成 bundle.harmony.js

其中pnpm dev实际执行的是 ReactProject/package.json 中定义的脚本:

"dev": "react-native bundle-harmony --dev false --bundle-output ../NativeProject/entry/src/main/resources/rawfile/bundle.harmony.js"

即通过 RNOH CLI 提供的bundle-harmony命令,把 JS 侧代码打包为bundle.harmony.js并直接输出到 NativeProject 的rawfile资源目录,后续 Harmony 工程会以ResourceJSBundleProvider的方式加载该 bundle(见 NativeProject/entry/src/main/ets/pages/Index.ets)。

3. 打开 Harmony 工程并等待同步

用 DevEco Studio 打开NativeProject,等待工程自动同步完成;若未自动同步,可手动执行Sync and Refresh Project。

4. 配置签名

点击File > Project Structure > Signing Configs,登录华为账号并完成自动签名。示例工程的签名配置声明在 NativeProject/build-profile.json5 的signingConfigs中。

5. 运行

点击 DevEco Studio 右上角run启动项目,即可看到示例界面。

提示:默认情况下 NativeProject 直接使用预编译好的third-party-library-sample/harmony/library.har;如需重新编译该 HAR,可在 build-profile.json5 中取消modules中library模块的注释,将三方件源码目录纳入构建。

三、三方件侧:如何编写一个可被自动链接的 RN 库

third-party-library-sample是理解自动链接入口的关键。它的 npm 包名(third-party-library-sample)与对外暴露的 Harmony 包名(@rnoh/third-party-library-sample)相互独立,分别由两份package.json/oh-package.json5声明。

3.1 npm 侧:声明 autolinking 配置与 codegen 脚本

third-party-library-sample/package.json 中有两处与自动链接直接相关的配置:

"scripts": { "codegen-lib": "react-native codegen-lib-harmony --no-safety-check --npm-package-name third-party-library-sample --cpp-output-path ./harmony/library/src/main/cpp/generated --ets-output-path ./harmony/library/src/main/ets/generated --cpp-components-spec-paths ./src/specs/cpp-components --turbo-modules-spec-paths ./src/specs/turbo-modules --arkts-components-spec-paths ./src/specs/arkts-components" }, "harmony": { "alias": "third-party-library-sample", "autolinking": { "cmakeLibraryTargetName": "third_party_library" } }
  • codegen-lib:调用 RNOH CLI 的codegen-lib-harmony命令,根据 specs 目录中的类型声明生成 ETS 与 C++ 的胶水代码(生成的代码输出到harmony/library/src/main/{cpp,ets}/generated),这是三方件能按 RN Fabric / TurboModule 规范工作的前提;
  • harmony.autolinking:自动链接的总开关。工具在扫描node_modules时,只有包内存在该字段才会被纳入链接(详见第五节源码分析)。cmakeLibraryTargetName指定 CMake 侧链接目标名,本示例为third_party_library。

3.2 specs:用 TypeScript 声明原生能力

三方件通过src/specs下三类声明文件描述自身能力:

  • ArkTS 组件SelectBox.ts:声明一个名为SelectBox的原生组件,包含data: SelectItems[]、onChange: DirectEventHandler<Res>等 props,以及一个emitNativeEvent命令(用于 RN 侧下发指令);
  • C++ 组件QDGestureFloatNativeComponent.ts:声明QDGestureFloat组件,带stopPercent、stopPercentMax两个浮点 props、onScroll事件和scrollTo命令;
  • TurboModuleSampleTurboModule.ts 与 SampleAnyThreadTurboModule.ts:分别声明同步方法add(a, b)与异步方法power(a, b)。

这些声明文件随后被codegen-lib转化为 ETS/C++ 的基类与胶水代码,并被 third-party-library-sample/index.ts 统一导出为SampleTurboModule、SampleAnyThreadTurboModule、SelectBox、QDGestureFloat四个符号,供 RN 侧import { ... } from 'third-party-library'使用。

3.3 Harmony 侧:实现 Package 与组件实例

三方件的 Harmony 源码位于 third-party-library-sample/harmony/library:

  • oh-package.json5:声明 Harmony 包名为@rnoh/third-party-library-sample,main指向Index.ets,并通过相对路径依赖 ReactProject 中安装的@rnoh/react-native-openharmonyHAR;
  • Index.ets:默认导出ThirdPartyLibrarySamplePackage——这是自动链接工具需要找到的RNOHPackage 入口类;
  • ThirdPartyLibrarySamplePackage.ets:继承RNOHPackage,注册组件描述符工厂、SelectBox的 UI 构建器,以及两个 TurboModule 的工厂 Map;
  • SelectBox.ets:ArkTS 组件实现,内部通过RNC.SelectBox.EventEmitter向 RN 回发change事件、通过CommandReceiver接收 RN 下发的emitNativeEvent命令;
  • SampleTurboModule.ets / SampleAnyThreadTurboModule.ets:分别实现同步add与 3 秒后返回结果的异步power;
  • CMakeLists.txt:将源码与generated目录下的 C++ 代码编译为third_party_library动态库,与package.json中cmakeLibraryTargetName对应;
  • QDGestureFloatComponentInstance.cpp:C++ Fabric 组件实例,实现带"吸顶/停留"逻辑的滚动容器(onScrollStop中根据stopPercent/stopPercentMax决定回弹到顶部还是停留)。

四、RN 侧接入:安装三方件并调用

4.1 依赖声明

ReactProject/package.json 通过file:协议安装本地打包产物:

"dependencies": { "react": "19.2.3", "react-native": "0.86.3", "@react-native-oh/react-native-harmony": "0.86.1", "third-party-library": "file:../third-party-library-sample/third-party-library-sample-1.0.0.tgz" }

同时使用 RNOH 提供的 Metro 配置 metro.config.js,通过createHarmonyMetroConfig合并默认配置,使 Metro 能正确处理鸿蒙化 bundle 的构建。

4.2 使用示例

ReactProject/App.tsx 展示了三种能力的典型调用方式:

import { QDGestureFloat, SampleAnyThreadTurboModule, SampleTurboModule } from 'third-party-library'; // TurboModule:同步调用与异步 Promise 调用 const result1 = SampleTurboModule.add(2, 4); SampleAnyThreadTurboModule.power(2, 4).then(result2 => setPowerResult(result2)); // Fabric 组件 + RN 向原生下发命令 <QDGestureFloat ref={floatRef} stopPercent={0.5} stopPercentMax={0.75} onScroll={(event) => console.log(event.nativeEvent.offsetY)} > {/* 点击"点击滚到顶"时通过 UIManager.dispatchViewManagerCommand 下发 scrollTo 命令 */} </QDGestureFloat>

其中"RN 向原生发送消息"通过UIManager.dispatchViewManagerCommand(findNodeHandle(ref), 'scrollTo', [...])完成;SelectBoxApp.tsx 中SelectBox组件的单选/多选切换与选项上报则分别依赖emitNativeEvent命令和onChange事件回调。

五、NativeProject 侧:自动链接是如何完成的

5.1 触发入口:link-harmony 命令

自动链接由 RNOH HvigorPlugin 在 Harmony 工程构建前调用link-harmony命令触发(命令实现见 packages/react-native-harmony-cli/src/commands/link-harmony.ts)。该命令支持以下参数:

参数默认值说明
--harmony-project-path./harmonyOpenHarmony 工程根目录
--node-modules-path./node_modules存放 npm 包的 node_modules 路径
--cmake-autolink-path-relative-to-harmony./entry/src/main/cpp/autolinking.cmake生成的 CMake 自动链接文件
--cpp-rnoh-packages-factory-path-relative-to-harmony./entry/src/main/cpp/RNOHPackagesFactory.hC++ 侧 Package 工厂文件
--ets-rnoh-packages-factory-path-relative-to-harmony./entry/src/main/ets/RNOHPackagesFactory.etsETS 侧 Package 工厂文件
--oh-package-path-relative-to-harmony./oh-package.json5Harmony 工程依赖声明文件
--exclude-npm-packages/--include-npm-packages无排除/仅包含指定 npm 包(二者互斥)

5.2 链接产物:四个被自动生成/更新的文件

核心逻辑位于 packages/react-native-harmony-cli/src/autolinking/Autolinking.ts,它通过 Mustache 模板批量生成四类文件:

  1. ETS 侧 Package 工厂(默认RNOHPackagesFactory.ets):import三方件包名并new出其RNOHPackage实例;
  2. C++ 侧 Package 工厂(默认RNOHPackagesFactory.h):#include三方件 C++ Package 头文件并make_shared创建实例;
  3. CMake 自动链接文件(默认autolinking.cmake):定义autolink_libraries(target)函数,为每个库执行add_subdirectory并链接到应用 target;
  4. oh-package.json5 依赖更新:清理无效的file:node_modules依赖,并为每个扫描到的 HAR 生成@rnoh/xxx: file:相对路径.har形式的托管依赖条目。

这些产物与工程中已有的接线代码相互配合:

  • NativeProject/entry/src/main/ets/PackageProvider.ets 与 PackageProvider.cpp 均通过createRNOHPackages(来自生成的工厂文件)装配三方件;
  • NativeProject/entry/src/main/cpp/CMakeLists.txt 中include(".../autolinking.cmake")后再调用autolink_libraries(rnoh_app),从而把三方件的 C++ 库链接进应用。

5.3 扫描与命名规则

Autolinking.prepareInput会遍历node_modules中所有依赖(通过ProjectDependenciesManager.forEachAsync),读取每个包的package.json.harmony.autolinking:

  • 未声明该字段、或被exclude/include名单排除的包会被记为skip,不参与链接;
  • 声明了的包会扫描其harmony目录下的.har文件,进而生成链接产物。

对于未显式指定类名/包名的库,工具按以下规则自动推导(见 Autolinking.ts#L474-L502):

  • ETS/C++ Package 类名:npmPackageName转 PascalCase 后追加Package后缀(scoped 包如@scope/name会拼接 scope 与包名);
  • CMake target 名:rnoh__+ snake_case 化后的包名;
  • oh-package 名:默认@rnoh/+ kebab-case 化后的包名,单个 npm 包内含多个 HAR 时追加--har文件名后缀区分。

六、运行效果与交互行为

启动应用后(见上文截图),可依次验证以下交互,这些行为由QDGestureFloat、SelectBox与两个 TurboModule 协作完成:

  1. 点击【点击滚到顶】,QDGestureFloat 内的内容滚动到顶部——对应 RN 侧UIManager.dispatchViewManagerCommand下发的scrollTo命令;
  2. 滚到顶部后向下拉松手,组件根据滚动位置决定停留在中间(stopPercent)还是回到顶部;
  3. 点击【选项1/2/3】,选项右侧会显示"选中"标记——由 SelectBox 的@Observed数据与@ObjectLink子项响应式渲染驱动;
  4. 点击【确定】按钮,VSCode 控制台打印当前选中项的 value,如{"target": 14, "value": [1]}——这是原生侧通过EventEmitter.emit('change', {value})回传给 RN 的onChange事件对象;
  5. 点击【现在是单选】按钮,文案切换为【现在是多选】,同时 RN 通过emitNativeEvent命令通知原生切换模式,之后可多选;
  6. 再次点击【确定】,控制台打印多选结果,如{"target": 14, "value": [1,2]}。

此外页面顶部还会展示2 + 4 = 6、2 ^ 4 = 16两个 TurboModule 的调用结果(同步add与 3 秒延迟的异步power),直观验证 JS ↔ 原生双向通信链路。

七、机制小结:一次link-harmony到底做了什么

结合 Autolinking.ts 的实现,可将 RNOH 自动链接归纳为"扫描 → 判定 → 解析 → 生成"四个阶段:

  1. 扫描:遍历node_modules下全部依赖,收集harmony目录内的.har文件;
  2. 判定:依据package.json.harmony.autolinking是否声明、include/exclude名单,决定每个包参与链接还是跳过;
  3. 解析:根据ohPackageName(字符串或"har 名 → 包名"映射数组)与默认命名规则,为每个 HAR 确定 oh-package 名称与版本策略(本地file:路径或远程版本号);
  4. 生成:渲染 ETS/C++ Package 工厂、autolinking.cmake,并通过JSON5Writer合并更新oh-package.json5依赖,随后由 RNOH HvigorPlugin 触发 Harmony 工程构建。

正因如此,开发者在接入一个新的 RNOH 三方库时,通常只需"在 RN 工程安装依赖 → 重新构建 Harmony 工程"两步,无需手工维护任何 Package 注册代码——这正是 AutolinkingSample 想要演示的核心价值。若需排查链接结果,可在构建日志中观察link-harmony输出的[link] 包名与[skip] 包名列表,快速确认哪些库被纳入、哪些被跳过。

  • OpenHarmony
  • 移动开发
  • 跨平台

【免费下载链接】ohos_react_native

React Native鸿蒙化仓库

项目地址:https://gitcode.com/CPF-RN/ohos_react_native
点击查看免费下载
上一篇:Proxmox VE Helper-Scripts多节点管理:集群状态监控
下一篇:终极招聘时间显示插件:如何不再错过任何机会?

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/14 2:08:36

数据库系统原理实战:从B+树、WAL到分布式事务的可验证体系

1. 这不是一本“教材”&#xff0c;而是一套可落地的数据库系统思维工具箱“数据库系统原理 全”——看到这个标题&#xff0c;很多人第一反应是&#xff1a;又一本高校教材&#xff1f;翻两页就困&#xff1f;堆满形式化定义和抽象模型&#xff1f;实话说&#xff0c;我刚接触…

作者头像 李华
网站建设 2026/10/14 2:06:28

Qt原生RSA加解密封装:绕过OpenSSL命令行的工程实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/14 2:06:22

无人自助拼豆系统全栈开发实战指南 核心功能实现与避坑经验分享

随着线下自助文娱业态的快速发展&#xff0c;无人值守的拼豆手工店正在成为商圈、社区的热门消费场景。用户无需店员接待&#xff0c;扫码即可解锁工位、领取材料包、自助完成拼豆创作&#xff0c;还可将未完成的作品寄存到共享柜中下次继续创作&#xff0c;整个流程完全自助化…

作者头像 李华
网站建设 2026/10/14 2:06:19

PyTorch实战:从教材PDF到可运行代码的工程化指南

简介&#xff1a;这是一份面向深度学习初学者与进阶开发者的经典英文原版教材《Deep Learning with PyTorch》PDF&#xff0c;由 Manning 出版&#xff0c;适合希望系统掌握 PyTorch 框架、从理论到工程落地完整学习的技术人员。资源包内共 1 个 PDF 文件&#xff0c;压缩包约 …

作者头像 李华
网站建设 2026/10/14 2:05:35

LTspice中文快速键一览表:从入门到肌肉记忆的键位指南

简介&#xff1a;这份LTspice中文快速键一览表面向电子技术与电磁学领域的电路设计初学者和仿真工程师&#xff0c;帮助解决软件操作不熟练、快捷键记忆零散、仿真分析效率低等问题。资源以PDF形式呈现&#xff0c;压缩包内共1个文件&#xff0c;大小约385KB&#xff0c;内容围…

作者头像 李华