☰
ohpm 入门:正确区分生产依赖、开发依赖与动态依赖
2026/10/20 6:23:37 网站建设 项目流程

ohpm 入门:正确区分生产依赖、开发依赖与动态依赖

专栏:HarmonyOS 三方库适配实战(3/30)
本篇目标:让依赖出现在正确的生命周期,而不是“哪里能装就写在哪里”。

摘要

HarmonyOS 工程的oh-package.json5可以声明dependencies、devDependencies和dynamicDependencies。三者不是三个随意选择的收纳盒:生产依赖会参与编译和运行,开发依赖只服务开发或测试,动态依赖用于配合动态导入表达 HSP 依赖。本文通过一个本地 HAR 示例说明应该把依赖放在哪里、如何安装、怎样确认最终依赖树,并分析把运行期库误放进开发依赖后的故障。

适用范围与完成标志

本文讨论模块或工程中的 ohpm 依赖声明,不讨论 HSP 的完整部署流程。你需要能找到目标模块的oh-package.json5,并知道哪个公开 API 会在正式代码中被调用。

完成本篇后,不只是“知道三个字段的中文名”,还应能给每个直接依赖写出使用阶段、消费模块、实际导入点和验证命令。无法说明用途的依赖,不应仅凭安装成功就保留。

先记住一个判断问题

不要先问“这个库叫什么”,先问:

最终应用在目标设备执行公开功能时,是否仍然需要这个依赖?

  • 如果需要,通常属于dependencies。
  • 如果只在开发、测试或构建辅助阶段使用,属于devDependencies。
  • 如果它是通过动态导入按条件加载的 HSP,才考虑dynamicDependencies。

图 1:依赖分类判断流程(示意图)。判断依据是发布产物中的运行责任。

华为官方oh-package.json5文档明确说明:生产依赖参与编译/运行;开发依赖只能参与开发或测试;动态依赖用于动态加载 HSP。三者的语义由交付方式和运行路径决定,不由包体积或使用频率决定。

示例:给应用接入一个本地 HAR

为了不假装某个远程示例包永远存在,本篇使用本地 HAR 路径。假设适配库包名为@demo/text-tool,产物放在模块的libs/text-tool.har。它是教学包名,不代表公共仓库中存在同名包。

在消费模块的oh-package.json5中配置:

{ "name": "entry", "version": "1.0.0", "main": "Index.ets", "dependencies": { "@demo/text-tool": "file:./libs/text-tool.har" }, "devDependencies": {} }

然后在包含该oh-package.json5的正确目录安装依赖:

ohpminstall--allohpm list-d10

官方安装 FAQ 特别提醒:安装成功却看不到依赖时,要先检查执行命令的目录。工程级和模块级都可能存在oh-package.json5,安装产物与修改的配置文件必须对应。排查时同时记录命令所在目录、配置文件位置和ohpm --version。

图 2:本地复现实验记录。HAR 被ohpm解析并参与 HAP 构建;设备调用仍待验证。

给 HAR 准备一个可观察 API

假设@demo/text-tool的公开入口导出下面函数。文件位置应由库工程的入口配置决定,例如Index.ets:

exportfunctionnormalizeSpaces(input:string):string{returninput.trim().replace(/\s+/g,' ')}

消费方通过包名导入,而不是跨目录引用库内部源码:

import{normalizeSpaces}from'@demo/text-tool'constinput:string=' HarmonyOS third-party library 'constoutput:string=normalizeSpaces(input)console.info(`normalized=${output}`)

若该库的公开契约就是压缩连续空白,预期输出可以写为:

normalized=HarmonyOS third-party library

这里的输出是根据示例函数推导的预期值,不是本轮设备日志。真实文章发布前,应使用目标 SDK 编译并在模拟器或真机读取实际日志。

dependencies:运行时仍需要的生产依赖

下面情况通常属于生产依赖:

  • 应用或 HAR 的公开源码中直接import的工具库;
  • 最终功能调用链上的组件、资源或 Native 库;
  • 消费方构建和运行都必须解析的依赖。

一个 HAR 如果公开 API 内部依赖另一个包,也要根据实际交付关系正确声明,不能指望消费方碰巧安装了相同依赖。

devDependencies:只服务开发与测试

典型例子包括:

  • 测试框架;
  • 只在本地生成代码或检查格式的工具;
  • 不进入最终运行调用链的开发辅助包。

不要因为“这个包只有调试时才容易出错”就放进开发依赖。判断标准仍然是最终产物运行时是否需要它。

下面是教学坐标,不代表公共仓库中存在该包;真正使用时要换成项目已经核对的测试工具及准确版本:

{ "devDependencies": { "@demo/test-runner": "1.0.0" } }

dynamicDependencies:动态导入的 HSP 依赖

动态依赖不是“偶尔使用的普通库”。官方添加依赖项文档说明,dynamicDependencies仅限动态依赖 HSP 的场景。只有工程确实采用动态加载设计,并且目标模块、产品和部署关系都满足要求时才使用。

概念配置如下:

{ "dynamicDependencies": { "feature_chat": "file:./libs/feature_chat.hsp" } }

在没有建立 HSP、动态加载和目标产品验证之前,不要为了“提升启动速度”把普通 HAR 随意移到这里。

故障复盘:把运行库放入devDependencies

假设entry在正式代码中导入@demo/text-tool,但配置写成:

{ "devDependencies": { "@demo/text-tool": "file:./libs/text-tool.har" } }

开发阶段可能因为缓存、其他模块或本地环境而暂时看不出问题,但它的声明已经与实际用途矛盾。排查步骤是:

  1. 从报错导入反查实际调用链;
  2. 查看当前模块的oh-package.json5;
  3. 使用ohpm list -d 10检查最终依赖位置;
  4. 将真正的生产依赖移到dependencies;
  5. 重新安装,并在干净环境构建消费模块;
  6. 记录锁文件和构建结果的变化。

不要只通过复制oh_modules目录来掩盖错误声明。那会让本机暂时通过,却让 CI 或新电脑失败。

用干净环境确认修复

调整依赖分类后,至少比较以下证据:

检查调整前调整后
oh-package.json5所在模块记录记录
ohpm list -d 10中的节点保存保存
锁文件是否变化是/否是/否
目标模块构建失败/未知实际退出状态
核心调用未执行/失败实际运行结果

不要删除锁文件和安装目录来制造“干净”。如果确需清理,先保存现场,再依据当前 ohpm 文档选择保留锁文件的方式。

一张可复用的依赖分类表

问题是否
正式源码是否直接或间接调用它?倾向dependencies继续判断
设备运行时是否必须携带它?dependencies继续判断
是否只用于测试、检查或开发辅助?devDependencies继续判断
是否通过动态 import 加载 HSP?dynamicDependencies不要使用动态依赖

本篇产物

  • 一个本地 HAR 的模块级依赖配置。
  • 一段公开入口与消费方调用代码。
  • 一套生产、开发和动态依赖的判断方法。

进入下一篇前,应该能运行ohpm list并指出每一个直接依赖为何出现在当前分类中。

官方来源

  • oh-package.json5:用于三类依赖的定义、远程/本地 HAR/源码等依赖方式。访问日期:2026-10-15。
  • 添加依赖项:用于确认dynamicDependencies仅限动态依赖 HSP 的场景。访问日期:2026-10-15。
  • 如何配置 oh-package.json5 动态依赖:用于生产、开发、动态依赖的当前说明。访问日期:2026-10-15。
  • ohpm list:用于查看直接和间接依赖。访问日期:2026-10-15。
  • ohpm 安装常见问题:用于命令执行目录与安装产物的排查。访问日期:2026-10-15。

验证声明

本文已于 2026-10-15 核对华为官方oh-package.json5、添加依赖项、动态依赖、ohpm list和安装 FAQ。实验工程已生成@demo/text-tool@1.0.0HAR,将其作为 entry 的dependencies本地文件依赖安装;ohpm list -d 10能读回该节点,安装与列表命令退出码均为 0,消费代码通过 API 22 目标 SDK 编译。@demo/*仍是本地教学坐标,不是公共仓库包;本轮没有实际 HSP、模拟器或真机验证。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询