如何在一个features下面创建多个HSP?

一、核心结论:逐个创建,统一管理

features/ 目录本质上只是一个普通的文件夹,它不像 entry 那样有特殊的系统含义。创建多个 HSP 的方式就是逐个在 features 目录下创建 Shared Library 模块 ,然后通过 oh-package.json5 管理它们之间的依赖关系。


二、创建步骤(DevEco Studio 操作)

步骤 1:创建 features 目录

在工程根目录下,新建一个名为 features 的空文件夹:

php 复制代码
MyApp/
├── entry/           ← 已有的 Entry 模块
├── features/        ← 手动创建的空文件夹(右键 → New → Directory)
└── ...

步骤 2:逐个创建 HSP 模块

操作入口(任选其一):

  • 方法 A :鼠标移到 features 目录上 → 右键 → NewModule
  • 方法 B :菜单栏 → FileNewModule

在弹出的创建向导中:

vbnet 复制代码
┌──────────────────────────────────────────┐
│  New Module                              │
│                                          │
│  Template:  Shared Library  ← 选这个!    │
│                                          │
│  Module name:  home       ← 第一个 HSP   │
│  Device type:  Phone / Tablet / ...      │
│  Enable native: □  (是否需要 C++)       │
│                                          │
│  [Finish]                                │
└──────────────────────────────────────────┘

⚠️ 模板选择 :一定要选 Shared Library,不要选 Static Library(那是 HAR)。

步骤 3:重复操作,创建多个 HSP

features/ 目录重复上述操作,逐个创建:

vbnet 复制代码
右键 features → New → Module → Shared Library → 输入「message」→ Finish
右键 features → New → Module → Shared Library → 输入「mine」    → Finish
右键 features → New → Module → Shared Library → 输入「search」  → Finish

步骤 4:验证结果

完成后,工程目录应如下:

java 复制代码
MyApp/
├── entry/
├── features/                    ← 手动创建的文件夹
│   ├── home/                    ← HSP 模块(Shared Library)
│   │   ├── src/main/ets/
│   │   ├── index.ets            ← 对外导出入口
│   │   ├── oh-package.json5
│   │   ├── module.json5
│   │   └── build-profile.json5
│   ├── message/                 ← HSP 模块
│   ├── mine/                    ← HSP 模块
│   └── search/                  ← HSP 模块
├── oh-package.json5             ← 工程级依赖
└── build-profile.json5          ← 工程级构建配置

三、配置模块间依赖关系

每个 HSP 模块独立存在,需要通过 oh-package.json5 声明谁来依赖谁。

典型依赖配置

bash 复制代码
entry → features/home
entry → features/message
entry → features/mine
features/home → common/uicomponents
features/message → common/network
json5 复制代码
// entry/oh-package.json5 --- 主模块依赖各个 feature
{
  "name": "@hm/entry",
  "dependencies": {
    "@hm/home": "file:../features/home",
    "@hm/message": "file:../features/message",
    "@hm/mine": "file:../features/mine",
    "@hm/common": "file:../common"
  }
}
json5 复制代码
// features/home/oh-package.json5 --- feature 依赖公共层
{
  "name": "@hm/home",
  "dependencies": {
    "@hm/uicomponents": "file:../../common/uicomponents"
  }
}
json5 复制代码
// features/message/oh-package.json5
{
  "name": "@hm/message",
  "dependencies": {
    "@hm/network": "file:../../common/network"
  }
}

添加依赖的操作方式

在 DevEco Studio 中,编辑完 oh-package.json5 后,把鼠标放在报错处会弹出提示,点击 Run 'ohpm install' 即可自动完成依赖映射。


四、每个 HSP 模块的内部结构

创建完模块后,需要按 MVVM 分层组织内部代码:

arduino 复制代码
features/home/
├── src/main/
│   ├── ets/
│   │   ├── model/                    ← 数据模型
│   │   │   └── ArticleItem.ets
│   │   ├── viewmodel/                ← 业务逻辑
│   │   │   └── HomeViewModel.ets
│   │   ├── view/                     ← UI 页面和组件
│   │   │   ├── HomePage.ets
│   │   │   └── ArticleCard.ets
│   │   ├── pages/                    ← 对外暴露的页面
│   │   │   └── HomePage.ets
│   │   └── constants/                ← 模块内常量
│   └── resources/                    ← 模块专属资源
├── index.ets                         ← ★ 统一导出
├── oh-package.json5
├── module.json5
└── build-profile.json5

index.ets --- 统一对外出口

typescript 复制代码
// features/home/index.ets
// 只导出需要被其他模块使用的部分

// 导出页面(供 entry 通过 router 跳转)
export { HomePage } from './src/main/ets/pages/HomePage'

// 导出 ViewModel(供 entry 直接使用)
export { HomeViewModel } from './src/main/ets/viewmodel/HomeViewModel'

// 导出公共组件
export { ArticleCard } from './src/main/ets/view/ArticleCard'

// 不导出内部实现:model 层的具体结构、工具函数等

五、在 Entry 中使用 HSP 的接口

typescript 复制代码
// entry/src/main/ets/pages/Index.ets
import { HomeViewModel, HomePage, ArticleCard } from '@hm/home'
import router from '@ohos.router'

@Entry
@ComponentV2
struct MainPage {
  private homeVM: HomeViewModel = new HomeViewModel()

  aboutToAppear(): void {
    this.homeVM.loadArticles()
  }

  build() {
    Column() {
      // 使用 HSP 导出的组件
      ArticleCard({ title: '今日推荐' })

      Button('跳转首页')
        .onClick(() => {
          // 通过页面路由跳转到 HSP 中的页面
          router.pushUrl({
            url: '@bundle:com.example.myapp/home/ets/pages/HomePage'
            //    └─ 格式:@bundle:包名/模块名/路径/页面文件名(不加.ets)
          })
        })
    }
  }
}

六、运行调试配置

多个 HSP 模块需要一起编译才能运行。在 DevEco Studio 中:

markdown 复制代码
1. 点击顶部工具栏的运行配置下拉框
2. 选择 Edit Configurations...
3. 在 Deploy Multi Hap 标签页 → 勾选:
   ☑ entry
   ☑ home (HSP)
   ☑ message (HSP)
   ☑ mine (HSP)
4. 点击 OK
5. 点击 Run 按钮

七、完整实践示例(创建 3 个 Feature HSP)

假设项目需求是三个 Tab 页面:首页、消息、我的。

第一步:创建目录与模块

bash 复制代码
# 在工程根目录执行(或通过 DevEco Studio GUI 操作)
mkdir features

# 通过 DevEco Studio 在 features 下创建三个 Shared Library 模块
# → 名为 home、message、mine

第二步:各模块编写代码

bash 复制代码
features/
├── home/
│   ├── index.ets               ← export { HomeViewModel, HomePage }
│   └── src/main/ets/
│       ├── model/HomeData.ets
│       ├── viewmodel/HomeViewModel.ets
│       └── view/HomePage.ets
│
├── message/
│   ├── index.ets               ← export { MessageViewModel, MessagePage }
│   └── src/main/ets/
│       ├── model/MessageItem.ets
│       ├── viewmodel/MessageViewModel.ets
│       └── view/MessagePage.ets
│
└── mine/
    ├── index.ets               ← export { MineViewModel, MinePage }
    └── src/main/ets/
        ├── model/UserInfo.ets
        ├── viewmodel/MineViewModel.ets
        └── view/MinePage.ets

第三步:Entry 模块组合所有 Feature

typescript 复制代码
// entry/src/main/ets/pages/MainTabs.ets
import { HomePage } from '@hm/home'
import { MessagePage } from '@hm/message'
import { MinePage } from '@hm/mine'

@Entry
@ComponentV2
struct MainTabs {
  @Local currentIndex: number = 0

  @Builder
  TabBuilder(index: number) {
    Tabs({ index: this.currentIndex }) {
      TabContent() { HomePage() }
        .tabBar('首页')
      TabContent() { MessagePage() }
        .tabBar('消息')
      TabContent() { MinePage() }
        .tabBar('我的')
    }
  }

  build() {
    this.TabBuilder(0)
  }
}

八、关键约束(务必注意)

约束 说明
不能单独运行 HSP HSP 必须跟随 HAP 一起安装运行,不能独立部署到设备 12
不能声明 Ability HSP 不支持在 module.json5 中声明 UIAbilityExtensionAbility
版本号一致 HSP 的 versionName / versionCode 必须与宿主 HAP 严格一致
不支持循环依赖 A 依赖 B,B 就不能再依赖 A
不支持依赖传递 A 依赖 B,B 依赖 C → A 不能直接使用 C 的接口
API 版本要求 HSP 及其使用方都必须是 API 10+ 的 Stage 模型
只支持模块化编译 所有相关模块都必须开启 modularize 编译模式

九、总结

在 features 下创建多个 HSP 的本质就是: 对 features 目录反复执行「右键 → New → Module → Shared Library」,每执行一次就多一个 HSP 模块。然后通过 oh-package.json5 把依赖关系串起来,通过各自的 index.ets 控制对外暴露的接口。

这套流程不复杂,但需要记住三个关键点:

  1. 模板选 Shared Library(不是 Static Library)
  2. 依赖只向下(entry → features → common)
  3. index.ets 守好门(只导出该暴露的,不泄露实现细节)
相关推荐
如此风景4 小时前
鸿蒙开发中 Model 类的组织方式
harmonyos
爱吃大芒果4 小时前
高密度数据可视化渲染:基于 ArkUI Grid 的状态热力图组件开发图纸
华为·信息可视化·harmonyos
心中有国也有家4 小时前
E-Brufen 技术选型全景:Flutter + 鸿蒙 + Hive CE
hive·hadoop·学习·flutter·华为·harmonyos
绝世番茄6 小时前
鸿蒙原生ArkTS布局方式之List+swipeAction侧滑菜单深度解析
华为·list·harmonyos·鸿蒙
Helen_cai6 小时前
OpenHarmony Preferences 本地持久化存储开发(API Version23 + 适配版)
华为·harmonyos
千逐687 小时前
UniApp 鸿蒙实战:音视频与多媒体处理完全指南
华为·uni-app·harmonyos·鸿蒙
国服第二切图仔8 小时前
HarmonyOS APP《画伴梦工厂》开发第51篇-Skill开发入门——VibeCoding与系统级智能入口
华为·harmonyos
哦***78 小时前
最后一块拼图补齐!华为大豆包时代开启✨
华为·音频·harmonyos
在书中成长8 小时前
HarmonyOS 小游戏《对战五子棋》开发第11篇 - AIPlayer设计概览:三档难度架构
华为·harmonyos