HAR / HSP 模块化拆分与跨包资源共享
·
HAR / HSP 模块化拆分与跨包资源共享
前言
当工程从「单 Module Demo」长成「多业务线的大型 App」,把所有代码塞进一个 entry 会让编译变慢、耦合爆炸。HarmonyOS 提供两种可复用包:HAR(HarmonyOS Archive,静态共享包) 与 HSP(HarmonyOS Shared Package,动态共享包)。本文讲清楚两者差异、何时用哪个,以及如何跨包共享资源与代码。
问题描述
- 多个业务模块都要用同一套网络层 / 工具函数,复制粘贴导致多份实现、改一处要改 N 处。
- 把公共代码抽成 HAR 后,包体积变大;抽成 HSP 后又遇到「资源找不到」「多个 HSP 重复打包」的问题。
- 跨包引用字符串、图片、ArkUI 组件时路径怎么写、怎么避免循环依赖。
细节解析
1. HAR vs HSP 怎么选
| 维度 | HAR | HSP |
|---|---|---|
| 形态 | 编译期静态链接进引用方 | 运行时动态加载,多模块共享同一份 |
| 包体积 | 每个引用方都含一份,体积偏大 | 全局一份,体积更优 |
| 资源 | 自带,编译进宿主 | 共享,需通过 $r 正确寻址 |
| 适用 | 纯工具库、组件库、可发布的三方库 | 多个 feature 共用的业务公共层 |
| 限制 | 不能包含 Ability | 不能独立上架,必须被 entry 依赖 |
经验法则:对外发布 / 无状态工具用 HAR;App 内部多模块共用的「重」公共层用 HSP。
2. 跨包引用代码
在引用方的 oh-package.json5 里声明依赖:
{
"dependencies": {
"mylib": "file:../mylib" // 本地源码依赖
}
}
代码里直接 import { httpGet } from 'mylib'。
3. 跨包引用资源
HSP 里定义 string.json / 图片后,引用方用带包名的 $r('mylib.string.key') 访问;HAR 资源则随编译进入宿主,使用方式相同。务必保证包名唯一且稳定,改名会导致所有 $r 失效。
4. 避免循环依赖
A 依赖 B、B 又依赖 A 会在编译期报错。解法:把共享部分下沉到第三个包 C,A、B 都只依赖 C。
示例代码
HSP 暴露一个公共网络函数(mylib/src/main/ets/network.ts):
// mylib/src/main/ets/network.ts
import { http } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';
export interface ApiResp<T> { code: number; data: T; }
export function requestJson<T>(url: string): Promise<T> {
return new Promise((resolve, reject) => {
const req = http.createHttp();
req.request(url, { method: http.RequestMethod.GET, connectTimeout: 10000 })
.then((resp) => {
if (resp.responseCode === 200) {
resolve(JSON.parse(resp.result as string) as T);
} else {
reject(new Error('HTTP ' + resp.responseCode));
}
})
.catch((e: BusinessError) => reject(e))
.finally(() => req.destroy());
});
}
引用方页面(entry):
import { requestJson } from 'mylib';
import { promptAction } from '@kit.ArkUI';
@Entry
@Component
struct Index {
build() {
Column() {
Button('拉取数据').onClick(async () => {
try {
const data = await requestJson<{ name: string }>('https://api.example.com/info');
promptAction.showToast({ message: data.name });
} catch (e) {
promptAction.showToast({ message: '请求失败' });
}
})
}.padding(20)
}
}
总结
- HAR 适合无状态工具/组件库与对外发布;HSP 适合 App 内部多模块共用的「重」公共层,节省体积。
- 依赖写在
oh-package.json5,代码用import { ... } from '包名'。 - 资源用带包名的
$r('包名.resource.key'),包名一旦确定不要改。 - 出现循环依赖时,把共享逻辑下沉到第三个包。
更多推荐



所有评论(0)