createRNOHModulePlugin & createRNOHProjectPlugin 配置说明
本文档统一说明 RNOH 中两个核心插件的配置规则:
createRNOHModulePlugin:用于配置 RNOH 模块插件行为(核心能力:Metro 调试、代码生成、原生模块自动链接);createRNOHProjectPlugin:用于配置 RNOH 工程级插件行为(核心能力:JS Bundle 打包)。
两个插件均包含 nodeModulesPath 配置项(参数名相同但各自独立),其余配置项为各自专属,具体划分如下:
| 配置项 | 归属插件 | 核心能力 |
|---|---|---|
nodeModulesPath |
createRNOHModulePlugin/createRNOHProjectPlugin(各自独立) |
定位 RN 工程依赖目录 |
metro |
createRNOHModulePlugin |
Metro 调试端口转发 |
codegen |
createRNOHModulePlugin |
ETS/C++ 代码生成 |
autolinking |
createRNOHModulePlugin |
原生模块自动链接 |
bundler |
createRNOHProjectPlugin |
JS Bundle 打包 |
前置说明
1. 路径基准规则
本文档中所有相对路径配置项(如 etsOutputPath、projectRootPath、bundleOutput 等),均以当前配置文件所在的Harmony工程根目录为基准,而非配置文件自身的目录。
2. 插件导入路径
两个插件均从 @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. 插件执行时机
createRNOHModulePlugin:在工程sync(同步/初始化)阶段执行,主要完成模块初始化、代码生成、自动链接等前置准备工作;createRNOHProjectPlugin:在工程编译构建 App 阶段执行,主要完成 JS Bundle 打包等构建相关操作。
一、nodeModulesPath 配置项(插件各自独立)
两个插件均包含 nodeModulesPath 配置项,参数名相同但取值和作用域相互独立,并非共享配置:
- 类型:
string - 作用:指定 React Native 工程的
node_modules目录位置,用于:- 定位 npm 包;
- 推导 Harmony 工程与 RN 工程的相对位置。
- 默认值:
../node_modules(以Harmony工程根目录为基准的上一级目录) - 使用建议:
- 当 RN 工程与 Harmony 工程不在典型的「同级目录结构」时,建议显式配置为根路径起始的完整路径或准确的相对路径;
- 若两个插件需指向同一 RN 工程的
node_modules,需手动配置相同值,而非依赖“共享”逻辑。
二、createRNOHModulePlugin 专属配置
顶层配置结构: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 调试配置:metro
export type MetroConfig = {
port?: number
}
功能说明
metro 字段用于配置 通过 hdc 进行端口转发(hdc rport) 的行为,方便在设备/模拟器无法直连开发机时,把设备上的端口转发到本机,从而访问本机正在运行的 Metro 服务。
注意:
- 这里的
metro不会启动 Metro 服务,也不会决定应用连接哪个端口;- 它只影响是否执行
hdc rport tcp:<port> tcp:<port>这条命令,以及用哪个端口去转发。
字段说明
port?: number- 作用:指定要通过
hdc rport转发的端口号(设备端口和本机端口相同)。 - 默认值:
8081 - 使用示例:
metro: { port: 8082, // 将设备上的 8082 端口转发到本机的 8082 } - 通常应与 实际 Metro 服务监听的端口 保持一致(例如用
react-native start --port 8082启动的端口),但真正的监听端口仍由 Metro 启动命令决定,而不是这里。
- 作用:指定要通过
启用 / 禁用规则
- 不写(
undefined)或写成空对象{}:- 表示开启端口转发功能,并使用默认端口
8081; - 等价于执行:
hdc rport tcp:8081 tcp:8081
- 表示开启端口转发功能,并使用默认端口
- 显式写
metro: { port: xxx }:- 表示开启端口转发,并使用指定的端口
xxx:hdc rport tcp:xxx tcp:xxx
- 表示开启端口转发,并使用指定的端口
- 显式写
metro: null:- 表示不会执行任何
hdc rport命令; - 不会影响应用是否去连接某个正在运行的 Metro 服务(只是不再由这个插件帮做端口映射)。
- 表示不会执行任何
2. 代码生成配置:codegen
export type CodegenConfig = {
/** RNOH 模块路径(兼容旧用法,可选) */
rnohModulePath?: string
/** ETS 代码生成输出目录 */
etsOutputPath?: string
/** C++ 代码生成输出目录 */
cppOutputPath?: string
/** RN 工程根目录,用于 codegen 的上下文定位 */
projectRootPath?: string
/** 是否输出调试信息 */
debug?: boolean
/** 是否跳过安全检查 */
noSafetyCheck?: boolean
}
功能说明
codegen 用于配置根据 JS/TS 代码生成 ETS / C++ 胶水代码的行为。
它会在指定的 RN 工程目录中,调用:
node_modules/.bin/react-native codegen-harmony
来生成 Harmony 侧与 RN 模块对应的接口定义和实现骨架。
启用 / 禁用规则
codegen: null:- 显式禁用代码生成功能;
- 不会执行任何
react-native codegen-harmony命令。
codegen: { ... }:- 启用代码生成,并根据提供的参数决定输出位置与行为;
- 启用时需满足:
etsOutputPath或rnohModulePath至少设置一个;- 且能够在
projectRootPath(或其默认值)下找到node_modules/.bin/react-native。
字段说明
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
export type AutolinkingConfig = {
ohPackagePath?: string
etsRNOHPackagesFactoryPath?: string
cppRNOHPackagesFactoryPath?: string
cmakeAutolinkPath?: string
excludeNpmPackages?: string[]
includeNpmPackages?: string[]
}
功能说明
autolinking 用于自动扫描 RN 项目中与 Harmony 相关的原生模块,并生成相应的绑定代码 / CMake 配置,避免手动维护重复配置。
字段说明
| 字段 | 作用 | 默认值 |
|---|---|---|
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 的第三方库列表 | [] |
启用 / 禁用规则
- 不写或写为
{}:启用 Autolinking,所有路径走默认值; - 显式写
autolinking: null:完全禁用 autolinking 行为。
三、createRNOHProjectPlugin 专属配置
顶层配置结构:RNOHProjectPluginOptions
export type RNOHProjectPluginOptions = {
/** RN 工程 node_modules 目录路径(插件独立配置) */
nodeModulesPath?: string
/** JS Bundle 打包配置;为 null 时表示显式禁用 */
bundler?: BundlerConfig | null
}
1. 打包配置: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
}
功能说明
bundler 用于配置在构建 Harmony 工程时的 JS Bundle 打包行为。
插件会在指定的 RN 工程目录中,调用:
node_modules/.bin/react-native bundle-harmony
来完成:
- 根据入口文件打包 JS/TS 代码(支持生成 Hermes 字节码 HBC 或普通 JS Bundle);
- 拷贝图片、字体等静态资源到指定目录;
- 生成 Source Map(可选);
- 基于 Hermes 引擎编译优化 Bundle(可选)。
启用 / 禁用规则
顶层 bundler 配置
bundler: null:显式禁用打包功能,不会执行任何打包子任务;bundler: { ... }:启用打包配置,根据字段控制bundle-harmony行为。
任务执行条件(hvigor 侧)
即使配置了 bundler: { ... },CreateJSBundle 任务执行还需满足:
if (
!this.input.nodeModulesPath ||
!bundlerOptions.enabled ||
buildMode !== "release"
) {
this.logger.warn(`[bundler] skipped`)
return
}
即需同时满足:
nodeModulesPath路径存在;bundler.enabled === true(默认true);- 当前构建模式为
release。
字段说明
| 字段 | 作用 | 默认值 | 补充说明 |
|---|---|---|---|
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 等 |
关键路径处理逻辑:
config/bundleOutput/assetsDest/sourcemapOutput配置的路径会被插件自动转换为相对于 RN 工程根目录的路径(RN 工程根目录 =nodeModulesPath向上推导一级),再传递给react-native bundle-harmony命令。
JS 引擎核心逻辑补充:
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)。
典型配置示例
// 生产环境配置(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
补充说明(基于底层源码执行逻辑)
-
参数透传规则:
enabled仅用于插件内部判断是否执行打包任务,不会传递给react-native bundle-harmony命令;dev会被自动转换为字符串类型(如true→"true")后传递给 CLI,插件层默认值"false"会覆盖 CLI 底层的true;hermescOptions插件层传入的字符串会被拆分为数组(如"O g"→["O", "g"]),底层会拼接为-O -g传递给 hermesc;- 路径类参数(
config/bundleOutput等)会被转换为相对 RN 工程根目录的路径,避免跨目录路径问题。
-
Hermes 字节码生成逻辑:
- 生成 HBC 时,底层会先将 JS Bundle 写入临时文件(系统临时目录 + 随机名);
- 调用对应系统的 hermesc 可执行文件编译临时 JS 文件为 HBC;
- 编译完成后自动删除临时 JS 文件,仅保留最终 HBC 文件;
- 若找不到 hermesc 可执行文件,会抛出明确错误并提示用户通过
--hermesc-dir指定路径(插件层已默认配置为./node_modules/react-native/sdks/hermesc/)。
-
执行上下文: 打包命令的执行目录(
cwd)固定为 RN 工程根目录(nodeModulesPath向上推导一级),确保node_modules/.bin/react-native能正确执行。 -
日志与错误处理:
- 打包成功会输出
[bundler] done generating bundle; - 打包失败会输出
[bundler] failed: 具体错误信息; - 未满足执行条件会输出
[bundler] skipped并跳过打包; - 生成 HBC 时若找不到 hermesc,会输出描述性错误并提示解决方案。
- 打包成功会输出
总结
-
默认值核心要点:
- 插件层默认值:
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 引擎关键规则:
- 仅支持
"any"/"hermes"两个取值; bundleOutput后缀为.hbc时,无论jsEngine配置为何,都会强制生成 Hermes 字节码;hermescOptions仅在生成 HBC 时生效,普通 JS Bundle 会忽略该参数。
- 仅支持
-
路径处理: 所有路径配置均基于Harmony工程根目录,插件自动转换为 RN 工程根目录相对路径,无需手动调整。
-
执行触发: 仅在
release构建模式、nodeModulesPath存在、enabled: true三个条件同时满足时,才会执行打包任务。
最终总结
- 插件分工与时机:
createRNOHModulePlugin在工程 sync 阶段执行(模块初始化),createRNOHProjectPlugin在编译构建阶段执行(打包); - 路径基准:所有相对路径均以Harmony工程根目录为基准,而非配置文件目录;
- 插件导入:两个插件均从
@rnoh/hvigor-plugin导入(实际路径在本地 hvigor 缓存目录); - 配置项独立性:
nodeModulesPath为两个插件各自独立的配置项(仅参数名相同),并非共享配置; - 核心差异:
bundler仅属于createRNOHProjectPlugin,metro/codegen/autolinking仅属于createRNOHModulePlugin; - 禁用规则:所有配置项设为
null可显式禁用对应功能,空对象{}则启用默认行为。