createRNOHModulePlugin & createRNOHProjectPlugin Configuration Guide
This document统一说明 RNOH中两个核心插件的配置规则:
createRNOHModulePlugin: 用于配置 RNOH模块插件行为(核心能力: Metro调试,代码生成,原生模块自动链接);createRNOHProjectPlugin: 用于配置 RNOH工程级插件行为(核心能力: JS Bundle打包).
两个插件均包含 nodeModulesPath配置项(参数名相同但各自独立),其余配置项为各自专属,具体划分如下:
| Configuration Item | Plugin | Core Capability |
|---|---|---|
nodeModulesPath |
createRNOHModulePlugin/createRNOHProjectPlugin(各自独立) |
定位 RN工程依赖目录 |
metro |
createRNOHModulePlugin |
Metro调试端口转发 |
codegen |
createRNOHModulePlugin |
ETS/C++代码生成 |
autolinking |
createRNOHModulePlugin |
原生模块自动链接 |
bundler |
createRNOHProjectPlugin |
JS Bundle打包 |
Prerequisites
1. Path Base Rule
All相对路径配置项(如 etsOutputPath, projectRootPath, bundleOutput 等)in this document,均以当前配置文件所在的Harmony工程根目录为基准,而非配置文件自身的目录.
2. Plugin Import Path
两个插件均从 @rnoh/hvigor-plugin包导入,该包的实际物理路径通常位于本地 hvigor缓存目录(不同用户路径略有差异):
// 统一导入方式
import {
createRNOHModulePlugin,
createRNOHProjectPlugin,
} from "@rnoh/hvigor-plugin"
示例物理路径: C:\Users\UserName\.hvigor\project_caches\project\workspace\node_modules\@rnoh\hvigor-plugin
3. Plugin Execution Timing
createRNOHModulePlugin: 在工程sync(同步/初始化)阶段执行,主要完成模块初始化,代码生成,自动链接等前置准备工作;createRNOHProjectPlugin: 在工程编译构建 App阶段执行,主要完成 JS Bundle打包等构建相关操作.
1. nodeModulesPath Configuration Item(插件各自独立)
两个插件均包含 nodeModulesPath配置项,参数名相同但取值和作用域相互独立,并非共享配置:
- 类型:
string - 作用: 指定 React Native工程的
node_modules目录位置,用于:- 定位 npm包;
- 推导 Harmony工程与 RN工程的相对位置.
- 默认值:
../node_modules(以Harmony工程根目录为基准的上一级目录) - 使用建议:
- 当 RN工程与 Harmony工程不在典型的「同级目录结构」时,建议显式配置为根路径起始的完整路径或准确的相对路径;
- 若两个插件需指向同一 RN工程的
node_modules,需手动配置相同值,而非依赖"共享"逻辑.
2. createRNOHModulePlugin Exclusive Configuration
Top-level Configuration Structure: RNOHModulePluginOptions
export type RNOHModulePluginOptions = {
/** RN工程 node_modules目录路径(插件独立配置) */
nodeModulesPath?: string
/** Metro hdc转发配置 */
metro?: MetroConfig | null
/**
* 代码生成配置;为 null时表示显式禁用.
* 若不为 null,必须至少指定 etsOutputPath或 rnohModulePath之一.
*/
codegen: CodegenConfig | null
/** 原生自动链接配置;为 null时表示显式禁用 */
autolinking?: AutolinkingConfig | null
}
1. Metro Debug Configuration: metro
export type MetroConfig = {
port?: number
}
Function Description
metro字段用于配置**通过 hdc进行端口转发(hdc rport)**的行为,方便在设备/模拟器无法直连开发机时,把设备上的端口转发到本机,从而访问本机正在运行的 Metro服务.
Note:
- 这里的
metro不会启动 Metro服务,也不会决定应用连接哪个端口;- 它只影响是否执行
hdc rport tcp:<port> tcp:<port>这条命令,以及用哪个端口去转发.
Field Description
port?: number- 作用: 指定要通过
hdc rport转发的端口号(设备端口和本机端口相同). - 默认值:
8081 - 使用示例:
metro: { port: 8082, // 将设备上的 8082端口转发到本机的 8082 } - 通常应与实际 Metro服务监听的端口保持一致(例如用
react-native start --port 8082启动的端口),但真正的监听端口仍由 Metro启动命令决定,而不是这里.
- 作用: 指定要通过
Enable/Disable Rules
- 不写(
undefined)或写成空对象{}:- 表示开启端口转发功能,并使用默认端口
8081; - 等价于执行:
hdc rport tcp:8081 tcp:8081
- 表示开启端口转发功能,并使用默认端口
- 显式写
metro: { port: xxx }:- 表示开启端口转发,并使用指定的端口
xxx:hdc rport tcp:xxx tcp:xxx
- 表示开启端口转发,并使用指定的端口
- 显式写
metro: null:- 表示不会执行任何
hdc rport命令; - 不会影响应用是否去连接某个正在运行的 Metro服务(只是不再由这个插件帮做端口映射).
- 表示不会执行任何
2. Code Generation Configuration: codegen
export type CodegenConfig = {
/** RNOH模块路径(兼容旧用法,可选) */
rnohModulePath?: string
/** ETS代码生成输出目录 */
etsOutputPath?: string
/** C++代码生成输出目录 */
cppOutputPath?: string
/** RN工程根目录,用于 codegen的上下文定位 */
projectRootPath?: string
/** 是否输出调试信息 */
debug?: boolean
/** 是否跳过安全检查 */
noSafetyCheck?: boolean
}
Function Description
codegen用于配置根据 JS/TS代码生成 ETS/C++胶水代码的行为.
它会在指定的 RN工程目录中,调用:
node_modules/.bin/react-native codegen-harmony
来生成 Harmony侧与 RN模块对应的接口定义和实现骨架.
Enable/Disable Rules
codegen: null:- 显式禁用代码生成功能;
- 不会执行任何
react-native codegen-harmony命令.
codegen: { ... }:- 启用代码生成,并根据提供的参数决定输出位置与行为;
- 启用时需满足:
etsOutputPath或rnohModulePath至少设置一个;- 且能够在
projectRootPath(或其默认值)下找到node_modules/.bin/react-native.
Field Description
rnohModulePath?: string
- 作用: 指定 RNOH模块的入口路径,用于推导 ETS输出路径(兼容旧的使用习惯);
- 一般推荐直接配置
etsOutputPath,rnohModulePath可在迁移阶段使用; - 当只配置
rnohModulePath而未显式配置etsOutputPath时,工具会基于该路径推导 ETS输出目录.
etsOutputPath?: string
- 作用: 指定生成的 ETS代码输出目录;
- 必填条件: 当
codegen启用时(不为null),etsOutputPath或rnohModulePath至少设置一个; - 默认值(逻辑默认):
codegen.rnohModulePath||./; - 典型配置:
codegen: { etsOutputPath: './entry/src/main/ets/generated', }
cppOutputPath?: string
- 作用: 指定生成的 C++绑定代码输出目录;
- 默认值(逻辑默认):
./entry/src/main/cpp/generated; - 典型配置:
codegen: { etsOutputPath: './entry/src/main/ets/generated', cppOutputPath: './entry/src/main/cpp/generated', }
projectRootPath?: string
- 作用: 指定 RN工程的根目录,用于代码生成时定位工程上下文(JS/TS源码,
node_modules目录,可执行文件); - 内部行为: 在
projectRootPath下执行node_modules/.bin/react-native codegen-harmony,因此该路径必须包含node_modules且已安装依赖; - 默认行为: 未配置时,使用 Harmony工程默认推断路径作为 RN工程根目录;
- 常见使用场景(RN与 Harmony工程分离):
codegen: { etsOutputPath: './entry/src/main/ets/generated', projectRootPath: '../react-native-app', // 相对 Harmony工程根目录的 RN工程路径 }
debug?: boolean
- 作用: 是否输出更详细的调试日志(排查 codegen问题);
- 默认值:
false.
noSafetyCheck?: boolean
- 作用: 跳过某些安全检查(路径合法性,环境检测等)(如 codgen命令报错文件操作权限相关可以设置为 true),仅高级场景/CI环境慎用;
- 默认值:
false.
3. Autolinking Configuration: autolinking
export type AutolinkingConfig = {
ohPackagePath?: string
etsRNOHPackagesFactoryPath?: string
cppRNOHPackagesFactoryPath?: string
cmakeAutolinkPath?: string
excludeNpmPackages?: string[]
includeNpmPackages?: string[]
}
Function Description
autolinking用于自动扫描 RN项目中与 Harmony相关的原生模块,并生成相应的绑定代码/CMake配置,避免手动维护重复配置.
Field Description
| Field | Description | Default Value |
|---|---|---|
ohPackagePath?: string |
指定 oh-package.json5的位置 |
./oh-package.json5 |
etsRNOHPackagesFactoryPath?: string |
指定 RNOHPackagesFactory.ets生成位置(ETS层注册包) |
./entry/src/main/ets/RNOHPackagesFactory.ets |
cppRNOHPackagesFactoryPath?: string |
指定 RNOHPackagesFactory.h生成位置(C++层注册包) |
./entry/src/main/cpp/RNOHPackagesFactory.h |
cmakeAutolinkPath?: string |
指定 autolinking.cmake生成位置(构建配置) |
./entry/src/main/cpp/autolinking.cmake |
excludeNpmPackages?: string[] |
指定不参与 Autolinking的第三方库列表 | [] |
includeNpmPackages?: string[] |
指定强制参与 Autolinking的第三方库列表 | [] |
Enable/Disable Rules
- 不写或写为
{}: 启用 Autolinking,所有路径走默认值; - 显式写
autolinking: null: 完全禁用 autolinking行为.
3. createRNOHProjectPlugin Exclusive Configuration
Top-level Configuration Structure: RNOHProjectPluginOptions
export type RNOHProjectPluginOptions = {
/** RN工程 node_modules目录路径(插件独立配置) */
nodeModulesPath?: string
/** JS Bundle打包配置;为 null时表示显式禁用 */
bundler?: BundlerConfig | null
}
1. Bundle Configuration: bundler
export type BundlerConfig = {
/** 是否启用 bundler任务 */
enabled?: boolean
/** 控制打包模式(开发/生产) */
dev?: boolean
/** 指定 bundle入口文件 */
entryFile?: string
/** 指定 Metro配置文件路径 */
config?: string
/** 指定 JS Bundle输出路径 */
bundleOutput?: string
/** 指定 JS引擎(仅支持 "any" / "hermes") */
jsEngine?: string
/** 指定静态资源输出目录 */
assetsDest?: string
/** 指定 Source Map输出路径 */
sourcemapOutput?: string
/** 控制是否压缩 JS代码 */
minify?: boolean
/** Hermes编译器额外参数(数组形式,最终拼接为字符串传递) */
hermescOptions?: string
}
Function Description
bundler用于配置在构建 Harmony工程时的JS Bundle打包行为.
插件会在指定的 RN工程目录中,调用:
node_modules/.bin/react-native bundle-harmony
来完成:
- 根据入口文件打包 JS/TS代码(支持生成 Hermes字节码 HBC或普通 JS Bundle);
- 拷贝图片,字体等静态资源到指定目录;
- 生成 Source Map(可选);
- 基于 Hermes引擎编译优化 Bundle(可选).
Enable/Disable Rules
Top-level bundler Configuration
bundler: null: 显式禁用打包功能,不会执行任何打包子任务;bundler: { ... }: 启用打包配置,根据字段控制bundle-harmony行为.
Task Execution Conditions(hvigor侧)
即使配置了 bundler: { ... },CreateJSBundle任务执行还需满足:
if (
!this.input.nodeModulesPath ||
!bundlerOptions.enabled ||
buildMode !== "release"
) {
this.logger.warn(`[bundler] skipped`)
return
}
即需同时满足:
nodeModulesPath路径存在;bundler.enabled === true(默认true);- 当前构建模式为
release.
Field Description
| Field | Description | Default Value | Additional Notes |
|---|---|---|---|
enabled?: boolean |
控制是否启用 bundler任务 | true |
执行前会被 delete移除,仅用于任务内部逻辑判断,不传递给 CLI |
dev?: boolean |
控制打包模式(开发/生产) | "false"(字符串类型,若传入布尔值会自动转为字符串) |
底层 CLI侧默认值为 true,插件层会覆盖为 "false"; true为开发模式(未压缩,含调试信息),false为生产模式 |
entryFile?: string |
指定 bundle入口文件 | index.js(CLI底层默认值) |
例如可配置为 index.tsx, src/main.tsx等,路径会被自动标准化 |
config?: string |
指定 Metro配置文件路径 | 无(CLI底层会自动查找 metro.config.js) |
配置后会自动转换为相对于 RN工程根目录的路径传递给 CLI |
bundleOutput?: string |
指定 Bundle输出路径(JS/HBC) | CLI底层默认规则: - jsEngine: "hermes" → ./harmony/entry/src/main/resources/rawfile/hermes_bundle.hbc- other → ./harmony/entry/src/main/resources/rawfile/bundle.harmony.js |
配置后会自动转换为相对于 RN工程根目录的路径传递给 CLI;若路径以 .hbc结尾,强制生成 Hermes字节码 |
jsEngine?: string |
指定 JS引擎 | "any"(CLI底层默认值) |
仅支持 "any" / "hermes";- "any": 生成普通 JS Bundle;- "hermes": 默认生成 HBC字节码(可被 bundleOutput覆盖后缀) |
assetsDest?: string |
指定静态资源(图片/字体等)输出目录 | ./harmony/entry/src/main/resources/rawfile/assets(CLI底层默认值) |
配置后会自动转换为相对于 RN工程根目录的路径传递给 CLI |
sourcemapOutput?: string |
指定 Source Map输出路径 | 无 | 配置后会自动转换为相对于 RN工程根目录的路径传递给 CLI;仅配置此参数才会生成 Source Map |
minify?: boolean |
控制是否压缩/混淆 JS代码 | CLI底层默认规则: minify = !dev(即生产模式默认 true) |
显式配置会覆盖底层默认逻辑; true减小包体积,false便于调试 |
hermescOptions?: string |
Hermes编译器额外参数 | "O"(插件层默认值); CLI底层无默认值 |
仅在 jsEngine: "hermes"时生效;插件层传入的字符串会被拆分为数组(如 "O g" → ["O", "g"]),底层会拼接为 -O -g传递给 hermesc;支持参数如 O(优化级别), g(生成调试信息), reuse-prop-cache等 |
Key Path Processing Logic:
config/bundleOutput/assetsDest/sourcemapOutput配置的路径会被插件自动转换为相对于 RN工程根目录的路径(RN工程根目录 =nodeModulesPath向上推导一级),再传递给react-native bundle-harmony命令.
JS Engine Core Logic Notes:
jsEngine: "hermes"仅改变默认输出文件名(hermes_bundle.hbc),但bundleOutput配置会覆盖该默认名;- 无论
jsEngine配置为何,只要bundleOutput路径以.hbc结尾,就会强制生成 Hermes字节码;- 生成 HBC时,底层会自动查找
./node_modules/react-native/sdks/hermesc/下对应系统的 hermesc可执行文件(macOS: osx-bin/hermesc, Linux: linux64-bin/hermesc, Windows: win64-bin/hermesc.exe).
Typical Configuration Examples
// 生产环境配置(Hermes引擎,生成 HBC字节码)
bundler: {
enabled: true, // 显式启用(默认true可省略)
dev: false, // 生产模式(默认false可省略)
minify: true, // 压缩代码(生产模式默认true)
jsEngine: 'hermes', // 指定Hermes引擎
config: "../metro.config.js", // Metro配置文件(相对Harmony工程根目录)
entryFile: "index.js", // 入口文件
bundleOutput: "./entry/src/main/resources/rawfile/hermes_bundle.hbc", // 生成HBC字节码
assetsDest: "./entry/src/main/resources/rawfile/assets", // 静态资源输出路径
sourcemapOutput: "./entry/src/main/resources/rawfile/hermes_bundle.map", // SourceMap路径
hermescOptions: "O" // Hermes编译参数
}
// 生产环境配置(普通 JS Bundle)
bundler: {
jsEngine: 'any', // 显式指定普通引擎(默认值可省略)
bundleOutput: "./entry/src/main/resources/rawfile/bundle.harmony.js", // 生成普通JS Bundle
assetsDest: "./entry/src/main/resources/rawfile/assets",
}
// 开发环境配置(精简)
bundler: {
enabled: true,
dev: true, // 开发模式(禁用压缩,保留调试信息)
minify: false, // 显式禁用压缩(dev=true时默认false)
}
// 禁用打包功能
bundler: null
Supplementary Notes(Based on底层源码执行逻辑)
-
Parameter Pass-through Rules:
enabled仅用于插件内部判断是否执行打包任务,不会传递给react-native bundle-harmony命令;dev会被自动转换为字符串类型(如true→"true")后传递给 CLI,插件层默认值"false"会覆盖 CLI底层的true;hermescOptions插件层传入的字符串会被拆分为数组(如"O g"→["O", "g"]),底层会拼接为-O -g传递给 hermesc;- 路径类参数(
config/bundleOutput等)会被转换为相对 RN工程根目录的路径,避免跨目录路径问题.
-
Hermes Bytecode Generation Logic:
- 生成 HBC时,底层会先将 JS Bundle写入临时文件(系统临时目录 +随机名);
- 调用对应系统的 hermesc可执行文件编译临时 JS文件为 HBC;
- 编译完成后自动删除临时 JS文件,仅保留最终 HBC文件;
- 若找不到 hermesc可执行文件,会抛出明确错误并提示用户通过
--hermesc-dir指定路径(插件层已默认配置为./node_modules/react-native/sdks/hermesc/).
-
Execution Context: 打包命令的执行目录(
cwd)固定为 RN工程根目录(nodeModulesPath向上推导一级),确保node_modules/.bin/react-native能正确执行. -
Logging and Error Handling:
- 打包成功会输出
[bundler] done generating bundle; - 打包失败会输出
[bundler] failed: 具体错误信息; - 未满足执行条件会输出
[bundler] skipped并跳过打包; - 生成 HBC时若找不到 hermesc,会输出描述性错误并提示解决方案.
- 打包成功会输出
Summary
-
Default Value Key Points:
- 插件层默认值:
enabled: true,dev: "false",hermescOptions: "O"; - CLI底层默认值:
entryFile: "index.js",jsEngine: "any",assetsDest: "./harmony/entry/src/main/resources/rawfile/assets"; bundleOutput底层默认值随jsEngine变化,minify底层默认值随dev变化.
- 插件层默认值:
-
JS Engine Key Rules:
- 仅支持
"any"/"hermes"两个取值; bundleOutput后缀为.hbc时,无论jsEngine配置为何,都会强制生成 Hermes字节码;hermescOptions仅在生成 HBC时生效,普通 JS Bundle会忽略该参数.
- 仅支持
-
Path Processing: 所有路径配置均基于Harmony工程根目录,插件自动转换为 RN工程根目录相对路径,无需手动调整.
-
Execution Trigger: 仅在
release构建模式,nodeModulesPath存在,enabled: true三个条件同时满足时,才会执行打包任务.
Final Summary
- Plugin分工与时机:
createRNOHModulePlugin在工程 sync阶段执行(模块初始化),createRNOHProjectPlugin在编译构建阶段执行(打包); - 路径基准: 所有相对路径均以Harmony工程根目录为基准,而非配置文件目录;
- Plugin Import: 两个插件均从
@rnoh/hvigor-plugin导入(实际路径在本地 hvigor缓存目录); - Configuration Item Independence:
nodeModulesPath为两个插件各自独立的配置项(仅参数名相同),并非共享配置; - Core Difference:
bundler仅属于createRNOHProjectPlugin,metro/codegen/autolinking仅属于createRNOHModulePlugin; - Disable Rules: 所有配置项设为
null可显式禁用对应功能,空对象{}则启用默认行为.