HarmonyOS鸿蒙Next中HAP引用HAR module后的第三方库问题

HarmonyOS鸿蒙Next中HAP引用HAR module后的第三方库问题

场景:需要开发了一个HAR 静态库的 moduleA提供给业务使用,在HAR A包中会引入其它的很多第三方的har和一些第三方远程库实现了一些二开功能。最终打包成HAR。

问题:HAR中包含了许多功能。是一个完整的。但是某个业务线只使用了其中一个功能,HAR就会冗余而且har包会很大。如何能按需依赖三方库。

例如:HAR里实现了有很多登录、分享、支付等功能方法,登录功能又是依赖第三方HAR B库实现好的。

理想的结果:A业务方依赖HAR,如只使用登录功能,需依赖第三方库登录库HAR B。如果只使用分享功能,就依赖第三方库HAR C即可。

HAR 库依赖情况:

在HAR module 的 oh-package.json5中devDependencies依赖了所有第三方库har来进行开发功能的实现

"devDependencies": {
  "xx":"xxx.har",
  "yy":"yyy.har",
  ...
  ...
}

业务方:HAP 的 oh-package.json5中

"dependencies": {
 // 封装的a.har
  "a":"a.har",
// 第三方har
  "login": "xx_login.har"
}

按上述方式实现a.HAR后给业务,业务方依赖了a.har和login.har后,编译提示not found xx.har,yy.har等,发现就是a.har实现好的其它功能的har如微信分享har、qq分享har、第三方支付har等所有第三方har包都得添加才能编译通过运行;

这种情况在android上一点没问题。可以开发一个sdk,在里面包含了所有功能实现。由外部自己去依赖第三方库。顶多使用到这个功能时提示报错找不到xxx类不存在。

如何解决这个问题??翻文档没有找到相关方案。求解答


更多关于HarmonyOS鸿蒙Next中HAP引用HAR module后的第三方库问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html

5 回复

【背景知识】

ArkTs开发时,通过oh-package.json5文件管理依赖,添加依赖方式有三种:远程三方包本地文件夹本地HAR/HSP包

引用三方HAR,包括从仓库进行安装、从本地文件夹和本地压缩包中进行安装三种方式。

devDependencies字段说明:配置开发态依赖,配置只能参与项目的开发或测试阶段的依赖。如果被依赖的组件最终要与依赖的组件一起发布到目标机器(如手机)上使用,则不能在其中配置。

【问题定位】

OHPM 客户端从 1.4.0 版本开始,同一项目下所有 Module 的依赖都会被统一安装在项目根目录下的 oh_modules 目录中,同时会在项目各 Module 下的 oh_modules 中生成该 Module 的直接依赖的软连接,这些软连接会指向项目根目录的 oh_modules/.ohpm 目录下对应依赖的实际存储目录,这个报错是直接依赖的子依赖配置的有问题。因为问题描述中ModuleA中依赖使用的是devDependencies,其中被依赖的组件无法被一起打包进去,这就导致业务方依赖a.har时无法找到xxx.har和yyy.har。

【解决方案】

上述问题,核心解决方式是让本地工程安装间接依赖时,保证可以正常下载到间接依赖,解决方式有以下3种:

方案一:将xxx.har和yyy.har安装包发布到远程仓库,a.har使用远程仓库依赖方式下载,具体实现方式:

  1. 将xxx.har和yyy.har包发布到远程仓库,修改a.har中依赖xxx.har和yyy.har方式,改成远程仓库依赖,可以解决间接依赖下载安装报错问题。发布远程仓库参考:发布共享包

  2. oh-package.json5中配置依赖:

{
  "dependencies": {
    "xxx":"1.0.0",
    "yyy":"1.0.0"
  }
}

方案二:将xxx和yyy模板移动到本地工程中,使用overrides复写xxx和yyy的依赖关系,具体实现方式:

  1. 将xxx和yyy工程迁移到本地项目下方。

  2. 在项目级oh-package.json5中使用overrides复写xxx和yyy的依赖关系,overrides会将a.har中的间接依赖复写使用项目级oh-package.json5中使用overrides下的依赖方式进行引用,由于xxx和yyy包已经移动到本地工程下,使用file:./xxx和file:./yyy方式进行本地依赖,可以正常找到xxx和yyy目录,即可解决xxx和yyy间接依赖报错。

方案三:将xxx和yyy打成har包,给a.har进行依赖,具体实现方式:

  1. 将xxx和yyy打成har包:DevEco Studio -> Build -> Make Module 'xxx’和DevEco Studio -> Build -> Make Module ‘yyy’,huild目录下生成对应的xxx.har和yyy.har。

  2. 在a中创建libs目录,将xxx.har和yyy.har包放到libs目录下,并进行依赖:

{
  "dependencies": {
    "xxx":"file:./libs/xxx.har",
    "yyy":"file:./libs/yyy.har"
  }
}
  1. 再将a打成har包,供本地工程使用,就不会再报错。

【修改建议】

上述三种方案中推荐使用方案一。

更多关于HarmonyOS鸿蒙Next中HAP引用HAR module后的第三方库问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


首先非常感谢你回答的解决方案!

但是你可能没理解我说的问题,并不是devDependencies问题,我是想说的是har存在多个冗余的三方库问题如何解决;

HarA是最终对外发布业务方使用的静态库,HarA依赖的本地的HarB、HarC、HarD…等以及远程三方库,这样打包后是不是就会在HarA里有很多三方库依赖,那就会存在冗余。因为业务并不会使用你的所有功能。

例如:HarA是一个二开的公共三方登录模块,然而三方登录方式有:①QQ登录 ②微信登录 ③微博登录 ④邮箱登录等等…,这样HarA会存在很多三方厂家库的依赖造成HarA包就会很大。那问题是如果在业务A上并不需要这么多登录方式,只要一个②微信登录功能,业务B需要②微信登录和③微博登录。但是业务A依赖了n个三方登录的功能。就会冗余。

理想情况是:HarA都不依赖有关第三方的依赖,只有功能的实现。所有用到的三方依赖由业务方自己按需依赖进来,像上述情况:

  • 业务A应该依赖两个包:HarA、微信登录Har的包就即可;
  • 业务B应该依赖三个包:HarA、微信登录Har、微博登录Har即可;

问题:项目编译期就会提示找不到没有依赖的这些所有第三方的包。始终绕不开依赖包的问题;看了鸿蒙的原理,目前没有这种机制。其实就是想实现像android上写lib时compileOnly依赖,ios上的重写第三方库类、前端的peerDependencies依赖一样。sdk使用到的三方库由业务去依赖来使用。并不是让sdk直接包死在里面。

如我对您的之前回答理解有误,或者您有解决方案,求解答或互相探讨。谢谢!!,

开发者您好,像android上写lib时compileOnly依赖,ios上的重写第三方库类、前端的peerDependencies依赖一样,目前鸿蒙上的确没有提供类似的能力,建议您可以从以下方面考虑方案:

  1. 所有登录相关的har全部打包进HarA,此时HarA包体积会很大,业务侧集成HarA,但是业务侧只import其中一个登录的代码如微信登录,可以观察此时业务侧hap包体积,编译时是否并没有把其他登录(如微博登录)的har包打包进hap包,这个需要进一步验证。

  2. 按照以下需求信息,我内部同步给对应开发人员分析后续是否会接受该需求,您看是否可以。

【原始场景】HarA是最终对外发布业务方使用的静态库,HarA依赖的本地的HarB、HarC、HarD…等以及远程三方库,这样打包后是不是就会在HarA里有很多三方库依赖,那就会存在冗余。因为业务并不会使用你的所有功能。

例如:HarA是一个二开的公共三方登录模块,然而三方登录方式有:①QQ登录 ②微信登录 ③微博登录 ④邮箱登录等等…,这样HarA会存在很多三方厂家库的依赖造成HarA包就会很大。那问题是如果在业务A上并不需要这么多登录方式,只要一个 ②微信登录功能,业务B需要 ②微信登录和 ③微博登录。但是业务A依赖了n个三方登录的功能。就会冗余。

理想情况是:HarA都不依赖有关第三方的依赖,只有功能的实现。所有用到的三方依赖由业务方自己按需依赖进来,像上述情况:

  • 业务A应该依赖两个包:HarA、微信登录Har的包就即可;
  • 业务B应该依赖三个包:HarA、微信登录Har、微博登录Har即可;

【影响】需要尽快提供该能力,否则后续会造成大量返工

【业界对标】android上写lib时compileOnly依赖,ios上的重写第三方库类、前端的peerDependencies依赖。android参考链接:https://developer.android.com/build/dependencies?hl=zh-cn

在HarmonyOS Next中,HAP引用HAR模块时,第三方库需确保与鸿蒙API兼容。HAR中的第三方库必须使用鸿蒙支持的TS/JS版本,且不能包含Java/C依赖。若遇到库冲突,检查依赖树是否包含非鸿蒙SDK的包。第三方库需通过方舟编译器验证,不兼容的库会导致HAP打包失败。确保所有依赖在module.json5中正确定义,且版本与鸿蒙NDK匹配。

在HarmonyOS Next中,HAR模块的依赖管理确实与Android有所不同。针对您的问题,建议采用以下解决方案:

  1. 模块化拆分方案: 将HAR A拆分为多个功能独立的子HAR模块(如login.har、share.har等),每个子模块只包含特定功能及其必要依赖。业务方可以按需引用具体功能模块。

  2. 条件编译方案: 在HAR A中使用动态导入(Dynamic Import)方式加载各功能模块,配合编译条件控制:

// 在HAR A中
export async function useLogin() {
  const loginModule = await import('xx_login');
  return loginModule.login();
}
  1. 依赖声明优化: 将devDependencies中的依赖改为peerDependencies声明:
// oh-package.json5
"peerDependencies": {
  "xx_login": ">=1.0.0",
  "xx_share": ">=1.0.0" 
}
  1. 运行时检测方案: 在HAR A中添加功能可用性检查:
export function isLoginAvailable() {
  try {
    require('xx_login');
    return true;
  } catch {
    return false;
  }
}

当前HarmonyOS的HAR机制要求所有依赖必须在编译时可用,这与Android的动态类加载机制不同。建议优先考虑模块化拆分方案,这是最符合ArkTS模块化设计理念的解决方案。

回到顶部