OpenHarmony HAR 静态共享组件库模块化拆分(API Version23 + 企业级分包方案)

📅 2026/7/14 5:22:11 ✍️ 编辑团队 👁️ 阅读次数
OpenHarmony HAR 静态共享组件库模块化拆分(API Version23 + 企业级分包方案)
摘要单 entry 模块存放全部页面、工具、组件会导致工程臃肿、编译缓慢、多人协作代码冲突、功能无法复用。HAR 静态共享库用于拆分独立业务模块、通用基础能力库实现代码解耦、多工程复用、分层隔离。API Version23 重构 HAR 依赖导入、资源互通、跨模块类型导出、编译缓存机制修复低版本 HAR 资源找不到、类型导入爆红、跨模块工具循环依赖、图片 rawfile 无法访问、多 HAR 编译冲突等兼容缺陷。旧项目升级 API23 后常出现导入 HAR 组件提示不存在、模型 interface 跨模块无法识别、rawfile 图片加载空白、同时引入多个 HAR 编译报错。本文基于 DevEco Studio API23完整讲解 HAR 库创建、依赖配置、跨模块资源 / 工具 / 组件调用、循环依赖规避、多模块分层架构实战封装基础通用能力 HAR、业务笔记模块 HAR 两套完整示例输出分包分层规范、导出约束、编译优化方案为大型鸿蒙项目模块化拆分提供标准化模板。关键词OpenHarmonyArkTSAPI Version23HAR静态共享库模块化拆分多模块工程代码复用分层架构一、引言1.1 HAR 分包开发背景小型课程设计单 entry 模块可正常开发但中大型项目、多人协作、多终端复用场景存在明显痛点所有代码堆在 entry文件上千打开工程卡顿、编译耗时久通用工具、自定义组件、数据模型无法给其他项目复用业务耦合严重删除某一功能会牵连大量页面代码多人开发容易出现文件命名冲突、git 合并大量冲突功能无法独立版本管控基础能力更新全项目重新编译。HARHarmony Archive静态共享库用于解决以上问题特点静态编译打包编译时合并至主模块运行无性能损耗可拆分通用基础库、独立业务模块库支持导出 ets 工具、自定义组件、类型、常量、资源支持多个 HAR 互相依赖主 entry 统一引入所有 HAR。OpenHarmony API Version23 HAR 核心升级变更严格控制跨模块导出权限未 export 的类 / 函数外部模块不可访问统一 rawfile、media 资源跨 HAR 访问路径规则修复图片资源加载失败优化循环依赖检测编译阶段直接抛出依赖环报错便于定位完善类型导出传递HAR 导出 interface 后 entry 可正常识别类型分模块编译缓存修改单个 HAR 仅重新编译该模块大幅提升编译速度区分 HAR 静态库与 HSP 动态共享库简化小型项目分包成本。大量旧项目升级后跨模块导入爆红、资源加载空白根源是未规范导出、资源路径写法错误、存在循环依赖因此掌握 HAR 分包是企业级大型项目必备架构能力。1.2 开发环境与分层场景开发工具DevEco Studio 5.0 适配系统OpenHarmony API23、HarmonyOS NEXT 模块类型entry主应用模块、多个 har 静态库模块 分包示例har_base全局工具、权限、网络、文件、通知、动画公共底层能力har_note笔记独立业务页面、CRUD、列表组件、数据库模型 测试场景主 entry 导入 har_base 工具、entry 引入 har_note 页面、HAR 之间互相依赖、跨模块资源访问、类型共享二、API23 HAR 核心约束与基础配置2.1 HAR 与 entry 核心区别表格模块用途能否独立运行页面注册Abilityentry主应用入口可独立安装运行module.json5 注册 pages可定义 EntryAbilityHAR 静态库代码 / 资源共享分包不可单独运行禁止注册 pages不允许定义 Ability2.2 module.json5 HAR 基础模板har_base 示例json{ module: { name: har_base, type: har, description: 全局基础工具库, deviceTypes: [phone], deliveryWithInstall: false, installationFree: false } }2.3 主 entry 引入 HAR 依赖entry module.json5jsondependencies: [ { name: har_base, version: 1.0.0, scope: shared }, { name: har_note, version: 1.0.0, scope: shared } ]2.4 跨模块导入路径规则导入 HAR 内 ets 代码import xxx from ohos:模块名/相对路径HAR 内部互相导入同标准相对路径../HAR 资源访问模块名、r (har 模块名:rawfile/xxx)2.5 API23 强制约束HAR 中所有需要外部访问的类、函数、interface、常量必须加 export私有代码禁止导出HAR 不能定义 UIAbility、不能在 module.json5 注册 pages 页面页面只能存放于 entry禁止双向循环依赖har_base 依赖 har_note 同时 har_note 依赖 har_base动态权限、数据库初始化上下文仅 entry 可提供HAR 工具仅接收外部传入 contextHAR 不支持 AppStorage 全局初始化全局状态统一在 entry EntryAbility 管理多个 HAR 同名资源会产生覆盖冲突资源文件名增加模块前缀区分。三、基础最简 HAR 导入示例3.1 har_base 内通用工具 har_base/src/main/ets/utils/toast_util.etsetsimport promptAction from ohos.promptAction // 必须export导出entry才能导入使用 export function showToast(msg: string) { promptAction.showToast({message: msg}) }3.2 entry 页面跨模块导入 HAR 工具ets// 固定格式 ohos:har模块名/文件相对路径 import { showToast } from ohos:har_base/utils/toast_util Entry Component struct Index { build() { Button(调用HAR封装Toast) .onClick(() showToast(来自基础HAR库工具)) } }3.3 HAR 共享数据模型 interfacehar_base/src/main/ets/model/NoteModel.etsetsexport interface NoteItem { id: number title: string content: string }entry 页面使用etsimport { NoteItem } from ohos:har_base/model/NoteModel State note: NoteItem {id:1, title:测试, content:HAR共享实体}四、完整分层多模块实战架构两套 HAR 分包完整代码整体工程目录结构plaintext项目根目录 ├─ entry主应用页面、EntryAbility、路由跳转 ├─ har_base基础底层HAR工具、常量、类型、通用组件 │ └─ src/main/ets │ ├─ utils 网络/文件/权限/通知/动画全套工具 │ ├─ model 全局interface、常量Constant │ └─ components 通用弹窗、加载组件 └─ har_note笔记业务HAR数据库操作、笔记专用组件、业务逻辑 └─ src/main/ets ├─ model 笔记业务实体 ├─ db 笔记RDB封装 └─ components 笔记条目ListItem组件4.1 实战一基础底层 HAR har_base 通用导出汇总har_base/src/main/ets/model/Constant.ets全局常量导出etsexport const STORAGE_KEY { IS_LOGIN: isLogin, DARK_MODE: darkMode } export const PAGE_ROUTE { INDEX: pages/index/index, NOTE_LIST: pages/note/NoteList }har_base/src/main/ets/components/LoadingDialog.ets通用组件导出etsComponent export struct LoadingDialog { build() { Column() { Text(加载中...) } .width(120) .height(100) .backgroundColor(#00000099) .borderRadius(12) } }har_base/src/main/ets/utils/permission_util.ets权限工具单例导出etsimport accessToken from ohos.accessToken import common from ohos.app.ability.common import { showToast } from ./toast_util class PermissionUtil { private static ins: PermissionUtil private ctx: common.UIAbilityContext | null null static getInstance() { if(!PermissionUtil.ins) PermissionUtil.ins new PermissionUtil() return PermissionUtil.ins } setContext(ctx: common.UIAbilityContext) { this.ctx ctx } async requestCamera(): Promiseboolean { if(!this.ctx) return false const status accessToken.checkAccessTokenSync(this.ctx, ohos.permission.CAMERA) if(status accessToken.GrantStatus.PERMISSION_GRANTED) return true const res await accessToken.requestPermissions(this.ctx, [ohos.permission.CAMERA]) if(res[0].grantStatus accessToken.GrantStatus.PERMISSION_GRANTED) return true showToast(未授予相机权限) return false } } export default PermissionUtil.getInstance()4.2 实战二业务 HAR har_note 笔记数据库与条目组件har_note/src/main/ets/db/note_db.ets依赖 har_base 工具etsimport relationalStore from ohos.data.relationalStore import common from ohos.app.ability.common import { showToast } from ohos:har_base/utils/toast_util import { NoteItem } from ohos:har_base/model/NoteModel class NoteDbUtil { private static ins: NoteDbUtil private store: relationalStore.RdbStore | null null private ctx: common.UIAbilityContext | null null static getInstance() { if(!NoteDbUtil.ins) NoteDbUtil.ins new NoteDbUtil() return NoteDbUtil.ins } setContext(ctx: common.UIAbilityContext) { this.ctx ctx } async init() { if(!this.ctx) return const config: relationalStore.StoreConfig { name: note_db, securityLevel: relationalStore.SecurityLevel.S1 } this.store await relationalStore.getRdbStore(this.ctx, config) await this.store.executeSql(CREATE TABLE IF NOT EXISTS note(id INTEGER PRIMARY KEY AUTOINCREMENT,title TEXT,content TEXT)) } async addNote(title:string, content:string): Promisenumber { if(!this.store) return -1 const bucket {title, content} return await this.store.insert(note, bucket) } async queryList(page:number, size:number): NoteItem[] { if(!this.store) return [] const pred new relationalStore.RdbPredicates(note) pred.offset(page*size).limit(size) const rs await this.store.query(note, [id,title,content], pred) let list: NoteItem[] [] while(rs.goToNextRow()){ list.push({ id: rs.getLong(0), title: rs.getString(1), content: rs.getString(2) }) } rs.close() return list } } export default NoteDbUtil.getInstance()har_note/src/main/ets/components/NoteItemCard.ets导出笔记条目组件etsimport { NoteItem } from ohos:har_base/model/NoteModel Component export struct NoteItemCard { Param data: NoteItem Param onDelete: () void build() { Row() { Column({space:4}).layoutWeight(1) { Text(this.data.title).fontSize(17) Text(this.data.content).fontColor(#666) } Button(删除).backgroundColor(#f56c6c) .onClick(() this.onDelete()) } .width(100%) .padding(16) .backgroundColor(Color.White) .borderRadius(10) } }4.3 实战三entry 主页面调用两套 HAR 完整示例 pages/note/NoteList.etsets// 导入基础HAR工具、常量、通用组件 import PermissionUtil from ohos:har_base/utils/permission_util import { LoadingDialog } from ohos:har_base/components/LoadingDialog import { PAGE_ROUTE } from ohos:har_base/model/Constant // 导入笔记业务HAR数据库、条目组件 import NoteDbUtil from ohos:har_note/db/note_db import { NoteItemCard } from ohos:har_note/components/NoteItemCard import { NoteItem } from ohos:har_base/model/NoteModel import RouterUtil from ../utils/router_util Entry Component struct NoteListPage { State list: NoteItem[] [] ctrl: CustomDialogController | null null async aboutToAppear() { // 给HAR工具传入页面上下文 const ctx getContext(this) PermissionUtil.setContext(ctx) NoteDbUtil.setContext(ctx) await NoteDbUtil.init() await this.loadData() } async loadData() { this.list await NoteDbUtil.queryList(0,10) } async delItem(id: number) { await NoteDbUtil.deleteNote(id) await this.loadData() } build() { Column({space:12}) { Text(笔记管理多HAR分包工程演示).fontSize(22).padding(10) List({space:10}).layoutWeight(1) { ForEach(this.list, (item:NoteItem){ ListItem() { NoteItemCard({ data: item, onDelete: () this.delItem(item.id) }) } }) } Button(返回首页).onClick(() RouterUtil.replace(PAGE_ROUTE.INDEX)) } .width(100%) .height(100%) .backgroundColor(#F5F5F5) } async aboutToDisappear() { await NoteDbUtil.closeDB() } }五、API23 HAR 模块化分层与编译优化规范5.1 分包分层规范单向依赖杜绝循环底层 har_base无任何其他 HAR 依赖提供通用基础能力业务 HARhar_note、har_user仅允许依赖 har_base业务 HAR 之间禁止互相依赖entry 主模块可依赖所有 HAR页面、Ability、全局状态全部放在 entry分层依赖流向entry → 业务 HAR → 底层 har_base单向不回流。5.2 导出编码规范所有对外可访问函数、类、组件、interface 必须添加 export仅暴露外部需要调用的 API内部辅助工具私有不导出单例工具使用export default常量 / 类型使用命名export const/interfaceHAR 内组件统一 Component exportentry 才能直接引入渲染。5.3 资源访问规范HAR 图片资源$r(har模块名:media/图片名)HAR rawfile 静态 HTML$r(har模块名:rawfile/index.html)不同 HAR 资源文件名增加模块前缀避免同名覆盖通用全局图片统一存放 har_base media 目录业务图片存放对应业务 HAR。5.4 编译性能优化规范按功能拆分多个小型 HAR不创建单个超大 HAR修改仅涉及单一 HAR 时仅该模块增量编译缩短等待时间稳定不变的底层基础能力抽离为独立 HAR极少重新编译调试阶段可临时移除未开发完成的 HAR 依赖加快编译速度。5.5 协作开发规范不同开发人员负责独立 HAR 模块代码隔离减少冲突HAR 对外 API 统一维护导出文件接口变更统一同步公共基础修改统一提交 har_base各业务模块同步更新依赖。六、API23 升级高频 HAR 兼容问题与解决方案问题 1entry 导入 HAR 代码提示爆红找不到模块 解决entry module.json5 添加对应 dependencies 依赖导入路径使用ohos:har名/标准前缀。问题 2HAR 内定义 interfaceentry 接收时报类型不匹配 解决实体 interface 统一放在底层 har_base 并 export 导出业务 HAR、entry 统一从 base 导入。问题 3HAR 中读取 media 图片空白无法显示 解决使用跨模块资源格式$r(har模块名:media/xxx)不使用本地相对资源写法。问题 4编译提示循环依赖报错 cyclic dependency 解决调整分层业务 HAR 只依赖底层 base业务 HAR 之间不互相导入。问题 5HAR 中调用 RDB/Preferences 提示上下文为空 解决HAR 工具仅提供方法由 entry 页面获取 context 传入 HAR 工具 setContext。问题 6多个 HAR 存在同名组件渲染出现错乱 解决组件、资源文件名增加 HAR 模块专属前缀避免命名冲突。七、总结HAR 静态共享库是 OpenHarmony 大型项目标准化分包方案API Version23 完善跨模块导出、资源访问、循环依赖检测、增量编译机制解决单 entry 工程臃肿、代码无法复用、编译缓慢、多人协作冲突等核心痛点。 标准分层架构底层基础 HAR 存放全局通用工具与基础组件各业务独立拆分为业务 HAR主 entry 仅负责页面与应用生命周期管理严格单向依赖杜绝循环耦合。全部代码兼容 API23 与 HarmonyOS NEXT适合课程设计大型综合项目、企业商用鸿蒙工程模块化改造。