HarmonyOS 7 API 26 依赖版本漂移检查示意图

先说问题:依赖版本漂移,通常不是编译器突然坏了

HarmonyOS 7 / API 26 项目升级时,除了 SDK 和 build-profile,依赖版本也很容易出问题。最常见的现象是:A 电脑能构建,B 电脑失败;昨天 CI 通过,今天同一分支突然失败;本地删掉缓存后,报错位置变了。

这类问题不要一上来就怀疑业务代码。先查 oh-package.json5、oh-package-lock.json5 和依赖解析结果有没有漂移。

环境和版本

项目 取值
系统方向 HarmonyOS 7.0.0 / API 26
工程方向 DevEco Studio、Hvigor、ohpm 依赖管理
关注点 依赖版本漂移、锁文件检查、CI 构建稳定性
验证方式 版本范围失败案例 + 锁文件通过案例

问题是怎么发生的

很多项目早期会在依赖里写版本范围,看起来方便升级:

{
  "dependencies": {
    "@ohos/some-lib": "^1.2.0",
    "@ohos/ui-kit": ">=2.0.0"
  }
}

问题是,版本范围会让“今天装出来的依赖”和“上次构建用的依赖”不一定完全一样。升级到 HarmonyOS 7.0.0 / API 26 后,这种漂移会更难排,因为你同时在改 SDK、改配置、改依赖。

案例一:先把风险版本找出来

可以写一个提交前检查,先把 ^、~、>= 这类范围版本找出来。

type DependencyMap = Record<string, string>

function findFloatingVersions(dependencies: DependencyMap) {
  const floating: Array<{ name: string; version: string }> = []
  for (const [name, version] of Object.entries(dependencies)) {
    if (/^[~^]/.test(version) || version.includes(">=") || version.includes("*")) {
      floating.push({ name, version })
    }
  }
  return floating
}

把前面的依赖放进去:

const dependencies = {
  "@ohos/some-lib": "^1.2.0",
  "@ohos/ui-kit": ">=2.0.0",
  "@ohos/safe-core": "3.1.4"
}

console.log(findFloatingVersions(dependencies))

输出:

[
  { name: "@ohos/some-lib", version: "^1.2.0" },
  { name: "@ohos/ui-kit", version: ">=2.0.0" }
]

这个输出能把风险点先圈出来。不是说所有范围版本都不能用,而是发版、审核、活动 Demo、多人协作项目里,关键依赖不要让它自己漂。

案例二:锁文件怎么参与验收

只检查 oh-package.json5 还不够,还要确认 lock 文件里解析出来的版本和期望一致。可以把关键依赖做成白名单。

type LockItem = { name: string; resolved: string }

function checkLockedVersions(lockItems: LockItem[], expected: DependencyMap) {
  const problems: string[] = []
  for (const [name, version] of Object.entries(expected)) {
    const actual = lockItems.find(item => item.name === name)
    if (!actual) {
      problems.push(name + " 没有出现在锁文件里")
      continue
    }
    if (actual.resolved !== version) {
      problems.push(name + " 解析版本不一致:" + actual.resolved + " != " + version)
    }
  }
  return problems
}

测试一个通过案例:

const lockItems = [
  { name: "@ohos/safe-core", resolved: "3.1.4" },
  { name: "@ohos/ui-kit", resolved: "2.4.1" }
]

console.log(checkLockedVersions(lockItems, {
  "@ohos/safe-core": "3.1.4"
}))

输出:

[]

空数组表示关键依赖符合预期,可以继续构建。

CI 里怎么落地

我会把检查分两步放到 CI 前面:

function assertNoDependencyRisk(dependencies: DependencyMap, lockItems: LockItem[]) {
  const floating = findFloatingVersions(dependencies)
  const lockProblems = checkLockedVersions(lockItems, {
    "@ohos/safe-core": "3.1.4"
  })

  const problems = [
    ...floating.map(item => item.name + " 使用了范围版本 " + item.version),
    ...lockProblems
  ]

  if (problems.length > 0) {
    throw new Error(problems.join("\n"))
  }
}

这段脚本不需要知道整个构建细节,只负责在构建前挡住明显不稳定的依赖状态。

几种方案怎么选

方案 优点 问题 适合场景
允许范围版本 升级快 构建结果不够稳定 个人 Demo
手动检查 lock 成本低 容易忘 临时排查
CI 检查关键依赖 要维护白名单 正式项目
全量依赖审计 最严 成本高 大项目、发版前

我的选择是第三种。关键依赖锁住,其它依赖按风险逐步收紧。这样升级 API 26 时,不会把依赖漂移和 SDK 兼容问题混在一起。

最后怎么验收

我会看四个结果:范围版本能被发现;关键依赖必须出现在 lock 文件里;解析版本和期望不一致时 CI 失败;报错信息能直接指出依赖名和版本。

HarmonyOS 7.0.0 / API 26 升级不是只改一处版本号。SDK、工程配置和依赖解析要一起收住。依赖不稳定,后面构建失败、审核复现失败、线上偶现问题都会变得更难查。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐