模块化设计与包管理 原创

游戏技术分享
发布于 2025-5-8 16:01
浏览
0收藏

1、应用程序包

多Module设计机制

一个应用通常会包含多种功能,将不同的功能特性按模块来划分和管理是一种良好的设计方式。在开发过程中,我们可以将每个功能模块作为一个独立的Module进行开发,Module中可以包含源代码、资源文件、第三方库、配置文件等,每一个Module可以独立编译,实现特定的功能。这种模块化、松耦合的应用管理方式有助于应用的开发、维护与扩展。

Module类型

Ability类型的Module: 用于实现应用的功能和特性。每一个Ability类型的Module编译后,会生成一个以.hap为后缀的文件,我们称其为HAP(Harmony Ability Package)包。HAP包可以独立安装和运行,是应用安装的基本单位,一个应用中可以包含一个或多个HAP包,具体包含如下两种类型:

  • entry类型的Module:应用的主模块,包含应用的入口界面、入口图标和主功能特性,编译后生成entry类型的HAP。每一个应用分发到同一类型的设备上的应用程序包,只能包含唯一一个entry类型的HAP,也可以不包含。
  • feature类型的Module:应用的动态特性模块,编译后生成feature类型的HAP。一个应用中可以包含一个或多个feature类型的HAP,也可以不包含。即应用程序包 = entry包 + n * feature包 (n >= 0)。

Library类型的Module: 用于实现代码和资源的共享。同一个Library类型的Module可以被其他的Module多次引用,合理地使用该类型的Module,能够降低开发和维护成本。Library类型的Module分为Static和Shared两种类型,编译后会生成共享包。

  • Static Library:静态共享库。编译后会生成一个以.har为后缀的文件,即静态共享包HAR(Harmony Archive)。
  • Shared Library:动态共享库。编译后会生成一个以.hsp为后缀的文件,即动态共享包HSP(Harmony Shared Package)。

选择合适的包类型

Module类型

包类型

说明

Ability

HAP

应用的功能模块,可以独立安装和运行,必须包含一个entry类型的HAP,可选包含一个或多个feature类型的HAP。

Static Library

HAR

静态共享包,编译态复用。

  • 支持应用内共享,也可以发布后供其他应用使用。
  • 作为二方库,发布到OHPM私仓,供公司内部其他应用使用。
  • 作为三方库,发布到OHPM中心仓,供其他应用使用。
  • 多包(HAP/HSP)引用相同的HAR时,会造成多包间代码和资源的重复拷贝,从而导致应用包膨大。
    注意:
    编译HAR时,建议开启混淆能力,保护代码资产。

Shared Library

HSP

动态共享包,运行时复用。

当多包(HAP/HSP)同时引用同一个共享包时,采用HSP替代HAR,可以避免HAR造成的多包间代码和资源的重复拷贝,从而减小应用包大小。

模块化设计与包管理-鸿蒙开发者社区

更多应用程序包信息可参考:

2、版本与依赖管理

关键字段

工程级oh-package.json5 依赖配置字段说明,完整文档参考​​oh-package.json5​​。

字段名称

字段说明

字段要求

字段类型

默认值

备注

dependencies

生产依赖

可选

对象

{}

用于配置参与编译/运行阶段使用的依赖,声明需要在代码中import的三方库(不建议在工程级oh-package.json5中配置生产依赖)。

devDependencies

开发依赖

可选

对象

{}

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

dynamicDependencies

动态依赖

可选

对象

{}

配置项目动态依赖的HSP模块。在开发者需要动态加载HSP的时候配置使用(不建议在工程级oh-package.json5中配置动态依赖)。

overrides

依赖覆盖配置

可选

对象

{}

支持将依赖树中的包替换为另一个指定版本,详情见​​overrides​​。

overrideDependencyMap

重写依赖关系

可选

对象

{}

支持将依赖树中包的子依赖替换为配置文件中配置的依赖,详情见​​overrideDependencyMap​​。

依赖配置优先级:overrides > resolve_conflict > overrideDependencyMap > oh_package.json5

ohpm私仓

ohpm-repo是一个搭建轻量级的HarmonyOS三方库私有仓服务的工具。它与ohpm包管理器兼容,用来存储和管理您独有的三方库,以保证这些三方包的私有性。同时,便于这些三方库能在开发团队内部共享复用,从而提升团队的开发效率。

下载ohpm-repo私仓工具包请前往​​ohpm-repo私仓工具包获取地址​​。

更多信息与搭建流程参考​​ohpm-repo私仓搭建工具​​、​​FAQ​​。

3、常见问题

如何正确处理HAR/HSP包模块间的依赖关系?

  • 推荐方式:import { add } from "library"。
  • 不推荐方式:使用相对路径或绝对路径进行引用:虽然技术上可行,但这种做法不推荐。使用相对或绝对路径引用模块会破坏模块间的隔离性,增加团队开发的管理和沟通成本,且难以维护。例如:import { add } from "../../library/src/main/ets/page/Index"。

为了保持代码的模块化、提高可维护性以及降低团队协作的复杂度,推荐使用包名进行模块间的依赖引用。避免使用相对或绝对路径,以维护项目的结构清晰和高效的团队合作。

HSP模块找不到?

该场景常常存在于hap依赖hsp模块的工程中,直接通过IDE安装至手机不会有问题,但是通过build > build hap编出来的hap包无法安装,是因为hsp是独立存在的,hsp和hap需要同时安装。

类似的多模块调试问题,请按需勾选Deploy Multi Hap Packages、Auto Dependencies。

更多内容请参考​​安装多个模块​​、​​自动安装依赖​​。

是否允许HAR的循环依赖?

不允许循环依赖。

是否允许传递依赖?

不支持传递依赖。

间接依赖的版本是不可控的,如果代码里使用到某个版本的间接依赖,不同时间安装的依赖可能版本不一致,程序运行可能出现意想不到的错误。举例说明:依赖关系:project->A(1.0.0)->B(^1.0.0)->C (latest)。

在dependencies只声明了A,但是工程中import了B和C。而B和C的版本是不可控的,如果C的开发者发布了一个2.0.0的版本,下次安装依赖时,可能会安装C的2.0.0的版本。然后就有可能出现一些问题,例如:在代码没有任何改动的情况下,程序运行却出现报错,不同时间不同PC上构建的应用运行表现不一致等。

所以ohpm为了解决幽灵依赖的问题,设计了一个特殊的存储结构,从技术上进行限制、不允许引用间接依赖,从而避免出现幽灵依赖问题。在上述例子中表现是:代码里只能引用A,引用B或C就会编译报错,提醒用户修改依赖配置。

HarmonyOS NEXT SDK版本不一致的情况下覆盖安装会报错。那么用户通过应用商店更新时,SDK版本不一致的包是否也会影响用户安装?

应用更新包的检查逻辑为:当两个版本的versionCode相同时,会检查apiReleaseType、minAPIVersion、targetAPIVersion,如果不一致则会报错。

因此sdk版本变更后,在编译打包前升级app.json5文件下的versionCode,即可实现覆盖安装。

oh-package.json5中版本号前^和~符号的含义?

版本号分为major、minor、patch,分别对应第一、二、三位。

  • 主版本号(major):当做了不兼容的API修改。
  • 次版本号(minor):当做了向下兼容的功能性新增,理解为Feature版本。
  • 修订号(patch):当做了向下兼容的问题修正,理解为Bug fix版本。

^表示从左边起,第一位非0数字不变,后续位大于等于当前版本。例如:

^1.2.2 代表 1.2.2 <= v < 2.0.0

^0.1.2 代表 0.1.2 <= v < 0.2.0

^0.0.1 代表 0.0.1 <= v < 0.0.2

~表示如果有第二位,则第二位不变,第三位可变;如果没有第二位,则第一位不变,第二、三位可变,例如:

~1.2.0 代表 1.2.0 <= x < 1.3.0

~1.3 代表 1.3.0 <= x < 1.4.0

~2 代表 2.0.0 <= x < 3.0.0


原文链接:​​华为开发者文章​


 更多问题可关注:

鸿蒙游戏官方网站:​​已有游戏移植-鸿蒙游戏-华为开发者联盟​

公开课:​​华为开发者学堂​

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
收藏
回复
举报
回复
    相关推荐