如何手把手打造鸿蒙应用第三方库HAR构建、混淆与发布?
摘要:【学习目标】 基于PreferenceLibDemo工程,掌握HAR库debug、release两种构建模式,完成字节码HAR与源码HAR的配置与构建。 掌握ArkGuard源码混淆与字节码混淆的开启方法,规则配置,确保Preference
【学习目标】
基于PreferenceLibDemo工程,掌握HAR库debug、release两种构建模式,完成字节码HAR与源码HAR的配置与构建。
掌握ArkGuard源码混淆与字节码混淆的开启方法,规则配置,确保Preference工具库对外接口可用。
完成HAR包签名配置,遵循标准流程将HAR发布到OpenHarmony三方库中心仓,实现跨项目复用。
掌握混淆与发布过程中的常见问题排查方法,保障工具库稳定交付。
一、基础概念:HAR的核心形态与定位
1.1 HAR定义
HAR(HarmonyOS Archive)是鸿蒙生态的静态库模块,本质是可复用的代码/资源打包文件,包含ArkTS/JS代码、资源文件、配置文件等,可被HAP(应用包)、HSP(鸿蒙共享包)或其他HAR依赖引用,实现代码复用。
类比:HAR相当于前端的npm包、Android的aar包,是鸿蒙生态中标准化的「代码复用单元」。
1.2 HAR的三种产物形态(核心区分)
产物类型
构建模式
核心构成
适用场景
安全性
构建/集成效率
字节码HAR
release(默认)
编译后的.abc字节码+资源
正式发布、对外提供SDK
高
构建慢/集成快
源码HAR
debug(默认)
完整ArkTS/TS源码+资源
本地开发、调试、联调
低
构建快/集成慢
源码HAR(混淆)
release
混淆后的JS中间码+资源
兼容旧版本环境
中
构建中/集成中
关键版本说明:从DevEco Studio NEXT Beta1(5.0.3.800)开始,release模式默认构建字节码HAR;若需构建源码HAR,需显式关闭byteCodeHar。
1.3 标准模块结构
本节内容基于上一节工程PreferenceLibDemopreferences模块实际目录结构如下,是HAR构建的基础:
preferences/
├─ build/ # 构建产物目录(自动生成)
├─ src/
│ ├─ main/
│ │ ├─ ets/
│ │ │ ├─ components/ # HAR库组件目录(按需保留/排除)
│ │ │ ├─ utils/ # 核心工具类目录
│ │ │ │ ├─ PreferencesConfig.ets # 配置类
│ │ │ │ └─ PreferencesUtil.ets # 核心工具类
│ │ │ ├─ resources/ # HAR库资源目录
│ │ │ └─ module.json5 # 模块基础配置
│ ├─ ohosTest/ # 鸿蒙测试目录
│ └─ test/ # 单元测试目录
├─ .gitignore # git忽略配置
├─ build-profile.json5 # 构建、混淆核心配置文件
├─ BuildProfile.ets # 构建配置辅助文件
├─ consumer-rules.txt # 依赖方混淆规则文件
├─ hvigor-config.json5 # 构建引擎的配置文件,定义开发态版本号、依赖插件的版本以及Hvigor相关能力的配置等
├─ hvigorfile.ts # 构建脚本
├─ Index.ets # HAR导出入口文件
├─ obfuscation-rules.txt # 本模块混淆规则文件
└─ oh-package.json5 # 包信息、版本与依赖配置
1.4 preference模块构建静态包信息(oh-package.json5)
{
"name": "@happy/preferences", // 构建har包名 @作者/组织 + 模块名称
"version": "1.0.0", // 版本号
"description": "Preferences多实例池工具库,支持多文件隔离、静态+实例双调用、XML/GSV自动降级", // 描述信息
"main": "Index.ets", // 导出文件入口
"deviceTypes": [ // 支持的设备类型
"default",
"phone",
"tablet"
],
"compatibleSdkVersion": "5.1.0(18)", // 最低兼容版本号
"author": "happy", // 作者
"license": "Apache-2.0", // 协议
"dependencies": {} // 依赖
}
重要提示
如果你要发布到第三方仓库,作者/组织名字必须通过组织管理审核通过才能用,否则发布har包会失败。
二、字节码HAR构建(release模式,主流发布形态)
默认产物是包含字节码的HAR包,其中包含abc字节码、资源文件、配置文件、readme、changelog声明文件、license证书文件,提升发布到ohpm中心仓产物的安全性。
2.1 核心特点
产物:编译后的.abc字节码 + 资源文件 + 配置文件(无原始源码)
核心优势:安全性最高(反编译难度大)、集成效率高(无需二次编译)、内存占用低
适用场景:开源库发布、对外SDK、正式商用
2.2 核心约束
工程需为Stage模型(API 10及以上),HAR模块类型为Static Library
工程级useNormalizedOHMUrl需设为true
字节码HAR的依赖需配置在自身oh-package.json5的dependencies/dynamicDependencies中
依赖名、import名、包名需完全一致(含大小写),否则集成时运行异常
HAR的compatibleSdkVersion不能大于集成工程的版本
修改oh-package.json5中的版本号后,必须先Clean Project再重新构建,否则版本不生效
三、ArkGuard 混淆配置表
3.1 混淆开关选项
混淆自定义选项名称
功能简述
混淆选项
关闭全局混淆
关闭所有混淆功能,不进行任何混淆
-disable-obfuscation
属性名称混淆
开启对象属性/变量名混淆
-enable-property-obfuscation
顶层作用域混淆
开启文件顶层变量/函数名混淆
-enable-toplevel-obfuscation
文件名混淆
开启构建产物文件名混淆
-enable-filename-obfuscation
导出名称混淆
开启export导出名称与属性混淆
-enable-export-obfuscation
代码压缩
精简代码格式,减小包体积
-compact
删除日志
自动删除代码中console.*打印方法
-remove-log
输出名称缓存
指定路径输出混淆映射表namecache.json
-print-namecache filepath
复用名称缓存
复用已有的混淆名称缓存文件
-apply-namecache filepath
删除注释
编译时删除代码中的所有注释
-remove-comments
3.2 白名单保留选项(保证API正常调用)
保留自定义选项名称
功能简述
保留选项
保留属性名
不混淆指定的属性名称
-keep-property-name
保留全局名称
不混淆顶层作用域与导出元素名称
-keep-global-name
保留文件名
不混淆指定文件/文件夹名称
-keep-file-name
保留类型声明
读取.d.ts文件内容作为混淆白名单
-keep-dts
保留注释
保留声明文件中JsDoc文档注释
-keep-comments
保留全量名称
保留指定路径下所有名称不被混淆
-keep
3.3 通配符说明
名称类和路径类的保留选项支持通配符,可批量配置白名单
四、核心配置步骤
4.1 工程级配置(根目录build-profile.json5)
必须开启 useNormalizedOHMUrl:true
// build-profile.json5
{
"app": {
"products": [
{
"buildOption": {
"strictMode": {
"useNormalizedOHMUrl": true // 字节码HAR必需开启
}
}
}
]
},
"modules": [{"name": "preferences", "srcPath": "./preferences"}]
}
4.2 模块级配置(preference/build-profile.json5)
byteCodeHar:true 开启字节码HAR,关闭字节码设置为false;
ruleOptions.enable = true 开启混淆;
{
"apiType": "stageMode",
"buildOption": {
"arkOptions": {
"byteCodeHar": true // 开启字节码HAR;关闭字节码设置为false
},
"resOptions": {
"copyCodeResource": {
"enable": false
}
},
// 可选:自定义打包内容,匹配实际目录
"packingOptions": {
"asset": {
"include": [
],
"exclude": [
"./src/main/ets/components/**/*" // 排除到har包外
]
}
}
},
"buildOptionSet": [
{
"name": "release",// 仅release模式生效
"arkOptions": {
"obfuscation": {
"ruleOptions": {
"enable": true, // 开启混淆
"files": [
"./obfuscation-rules.txt" // 混淆规则文件
]
},
// consumerFiles中指定的混淆配置文件会在构建依赖这个library的工程或library时被应用
"consumerFiles": [
"./consumer-rules.txt"
]
}
}
}
],
"targets": [
{
"name": "default"
},
{ "name": "ohosTest" }
]
}
4.2.1 packingOptions 核心配置说明
include
定义需要打入HAR包的资源路径
支持通配符 **/* 表示递归匹配所有子目录文件
若留空则表示默认包含除exclude外的所有资源
exclude
优先级高于include
示例中排除了 components 目录下所有内容
被排除的资源不会出现在最终HAR包中
4.3 字节码混淆规则 obfuscation-rules.txt
# ========================
# 混淆总开关
# ========================
-enable-bytecode-obfuscation # 开启字节码混淆(必须)
-enable-property-obfuscation # 开启属性名混淆
# -enable-filename-obfuscation # 关闭:文件名混淆
-enable-toplevel-obfuscation # 开启顶层作用域混淆
# -enable-export-obfuscation # 关闭:export导出名称混淆 否则我们的har包其他应用无法使用
# ========================
# 代码优化 我们不需要 打包发布应用时可开启
# ========================
# -compact # 关闭:代码压缩 会变成一行 不利于其他开发人员查看接口
# -remove-log # 关闭:删除日志
# -remove-comments # 关闭:删除注释 我们做开源库注释给其他开发人员看的
-print-namecache ./namecache.json # 输出混淆映射表
# ========================
# 白名单:保留对外暴露的全局名称
# ========================
-keep-global-name PreferencesUtil
-keep-global-name PreferencesOptions
-keep-global-name StorageMode
-keep-global-name ChangeCallback
# ========================
# 白名单:保留对外暴露的方法名
# ========================
-keep-property-name getInstance
-keep-property-name use
-keep-property-name getCurrentInstance
-keep-property-name getCurrentFileName
-keep-property-name put
-keep-property-name get
-keep-property-name has
-keep-property-name delete
-keep-property-name onDataChange
-keep-property-name offDataChange
-keep-property-name removeAllListeners
-keep-property-name deleteFile
-keep-property-name destroy
-keep-property-name destroyFile
4.4 consumer-rules.txt
# 给依赖当前HAR的项目自动应用白名单规则
-keep-global-name PreferencesUtil
-keep-global-name PreferencesOptions
-keep-global-name StorageMode
-keep-global-name ChangeCallback
-keep-property-name getInstance
-keep-property-name use
-keep-property-name getCurrentInstance
-keep-property-name getCurrentFileName
-keep-property-name put
-keep-property-name get
-keep-property-name has
-keep-property-name delete
-keep-property-name onDataChange
-keep-property-name offDataChange
-keep-property-name removeAllListeners
-keep-property-name deleteFile
-keep-property-name destroy
-keep-property-name destroyFile
4.5 执行构建
选中 preferences 模块;
点击顶部菜单栏 Build → Clean Project(清理旧构建产物);
点击右上角 Build Mode → 选择 release;
点击顶部菜单栏 Build → Make Module 'preferences';
构建完成后,查看产物路径:preferences/build/default/outputs/default/preferences.har
我们要构建HAR工具包发布到第三方开源仓库供他人使用。因此导出元素混淆必须关闭,其他混淆开启即可,否则 HAP/HSP 依赖时会报导出错误。
本节内容中 # 为注释,去掉注释则开启对应功能。
BuildMode模式选择
解压HAR包
文件名没有混淆(开源便于其他开发人员查看)并且导出了全部的公共接口,其内部实现隐藏。
modules.abc:是工程中所有 .ets/.ts/.js文件编译后的字节码集合,包含应用逻辑和 UI 声明式代码,由鸿蒙运行时环境直接解析执行。
验证HAR包可用性
将har包导出到其他工程引用,所有接口、字段名称都可正常访问。
五、混淆效果与堆栈还原
5.1 混淆效果
字节码混淆完成后,会在工程 build 目录下build/default/.../release/obfuscation生成一系列混淆中间产物与映射文件。通过这些文件查看混淆结果、还原崩溃堆栈。
nameCache.json:混淆名称映射表,记录混淆前后类名、方法名、属性名的对应关系。
systemApiCache.json:系统API白名单文件,记录SDK标准接口名称,与这些名称重名的自定义元素不会被混淆。
obf 目录:存放混淆后的最终字节码文件modules.abc,开启调试配置后还会生成 modules.pa 文件。
origin 目录:存放混淆前的原始 modules.abc 文件,用于对比校验。
config.json:混淆配置记录文件,保存本次混淆使用的规则、白名单等信息。
5.2 报错堆栈还原
代码经过字节码混淆后,类名、方法名会被替换成无意义字符,程序崩溃时输出的堆栈信息无法直接对应源码,难以排查问题。
此时可使用 DevEco Studio 自带的 hstack 反混淆工具,通过混淆映射文件还原出原始源码堆栈。
反混淆还原需要两个关键文件:
对外发布开源库/SDK后,若需线上排查崩溃问题,必须本地备份好 编译生成的 sourceMaps.json 、混淆映射表 nameCache.json,建议直接备份整个 release 目录。
字节码HAR构建耗时相对更长(需将源码编译成二进制字节码),但集成到宿主工程时无需二次编译,可节省 50% 以上的编译时间。
5.3 代码体积优化
若构建时出现代码体积过大相关报错,可在 build-profile.json5 中添加以下配置:
默认值:若不配置,默认为 2000。
合法范围:配置值必须满足 1 ≤ maxFlowDepth ≤ 65535。
超限报错:若值超过 65535
"arkOptions": {
"tscConfig": {
"maxFlowDepth": 3000
}
}
六、源码HAR
6.1 核心前提
无论debug还是release模式构建源码HAR,必须先关闭字节码HAR开关:
{
"buildOption": {
"arkOptions": {
"byteCodeHar": false // 核心:关闭字节码,生成源码HAR
}
}
}
6.2 debug模式构建
6.2.1 核心特点
产物:完整、未混淆的ArkTS/TS源码 + 资源文件 + 配置文件
支持断点调试、热重载,开发效率高
仅用于本地开发、内部调试,不对外发布
6.2.2 配置与构建
模块级build-profile.json5中配置byteCodeHar: false
点击右上角Build Mode选择debug
点击Build → Clean Project清理工程
选中preference模块 → 点击Make Module preferences
构建完成后,得到包含完整.ets源码的HAR包
6.3 release模式构建
建议开启混淆,保护代码资产。
6.3.1 核心特点
产物:混淆后的JS中间码 + 资源文件(无原始源码)
安全性中等,兼容性强
使用场景:仅用于兼容不支持字节码的老旧开发环境
新版OpenHarmony 开源库发布不使用该格式
6.3.2 配置与构建
模块级配置文件中设置byteCodeHar: false
确保release模式下混淆配置已开启
混淆规则文件中必须注释字节码开关 -enable-bytecode-obfuscation(删除或者注释掉)
点击右上角Build Mode选择release
执行Clean Project清理整个项目中的编译产物
选中需要打包的模块文件,执行Make Module进行构建
得到混淆后的JS中间码形态HAR包
6.4 源码打包文件混淆后的效果
七、字节码HAR vs 源码HAR 核心对比
维度
字节码HAR(release)
源码HAR(debug)
源码HAR(release+混淆)
产物形态
.abc字节码
完整.ets源码
混淆JS中间码
调试支持
不支持
支持
不支持
安全性
极高
低
中
开源库发布
✅ 标准格式
❌ 不使用
❌ 不使用
适用场景
正式发布/开源SDK
本地开发、内部调试
兼容旧版本环境
关于源码打包作为了解,本节我们还是以字节码为主,将配置内容调整到字节码以便接下来发布har包做好准备。
八、HAR共享包发布与跨项目使用
8.1 准备发布
注册登录 OpenHarmony 三方库中心仓账号,并完成实名认证,这是发布三方库的前提。
创建存放密钥的文件,示例在系统目录创建默认隐藏文件夹.ssh_ohpm,~/.ssh_ohpm/preferenceskey 为私钥文件路径。不要把密钥放在项目工程里提交到Git。
使用 ssh-keygen 工具生成加密密钥对,用于身份认证与安全发布。
终端执行命令生成密钥:
ssh-keygen -m PEM -t RSA -b 4096 -f ~/.ssh_ohpm/preferenceskey
8.2 执行结果
公钥私钥存放在同一目录下,preferenceskey.pub 为公钥。
8.3 找到公钥(.pub)
8.4 配置公钥
用文本编辑器打开公钥,复制内容到OHPM后台认证管理中,提示添加成功。
8.5 必需文件(模块根目录)
README.md:库介绍、使用说明、依赖方式
CHANGELOG.md:版本更新记录
LICENSE:开源许可协议文件
8.6 发布前注意
发布前必须重新Clean Project并构建,确保LICENSE文件打入HAR包,否则发布失败。
8.7 获取发布ID
8.8 发布命令
cd preferences
ohpm config set key_path ~/.ssh_ohpm/preferenceskey
ohpm config set publish_id 你的发布ID
ohpm publish ./build/default/outputs/default/preferences.har
8.9 发布结果
发布HAR包成功
发布HAR包审核消息
8.10 跨项目使用
HAR发布并通过审核后,在其他项目直接安装,在之后的章节中如有需要用到preferences直接开启使用。
# 安装
ohpm install @happy/preferences
# 卸载
ohpm uninstall @happy/preferences
九、内容总结
字节码HAR(release):开源库标准格式,安全高效,正式发布必须用它。
源码HAR(debug):纯源码,仅用于本地调试。
源码HAR(release):混淆JS中间码,仅用于兼容老旧环境,新版不用。
混淆仅在release模式生效,必须保留工具库对外接口。
签名+发布是开源库标准化流程,是SDK开发必备技能。
十、代码仓库
工程名称:PreferenceLibDemo
仓库地址:https://gitee.com/HarmonyOS-UI-Basics/harmony-os-ui-basics.git
十一、下节预告
下一节,我们将学习鸿蒙生态中 最轻量化的UI复用方案 。你将掌握 @Builder 组件内/全局双模式定义 、按值/按引用传参与刷新机制 @BuilderParam 插槽高级用法 ,并彻底搞懂 this指向在组件传递中的核心规则 ,快速实现UI片段高效复用,为后续封装可复用轻量UI元素做基础准备。
