一个项目昨天能打包,今天拉取同一个分支却出现新问题,未必是 ArkTS 代码发生了变化。某些团队会把模块依赖版本写成 ^1.4.0 或 *,然后只盯着 Git 中的页面文件;一旦重新安装依赖,解析结果就可能随着仓库中的包版本变化。问题并不总是出在版本范围本身,而是代码评审看不见依赖树为何变化。这次把检查提前到构建之前。示例工程叫 DependenceGate,演示报告编号 DG-102。它不尝试发明一个新包管理器,而是做一个很窄的“配置风险门禁”:查看生产依赖的声明范围、列出需要人工复核的条目,再提示保存 oh-package-lock.json5 作为可复现依据。示例包名以 @example/ 开头,纯属本地样例名称,不能据此去公共仓库安装。## 一、构建能过,不代表下次解析还是同一棵树oh-package.json5 负责声明依赖意图,oh-package-lock.json5 用于锁定解析后的依赖版本及依赖树信息。根据华为 2026 年发布的相关文档,建议将锁文件提交版本管理;不建议手动改写锁文件,也不建议将它作为自定义分析脚本直接读取的接口。工程根目录与模块目录的依赖字段职责也不同:应用运行时需要的包一般应由相应模块在 dependencies 中声明,开发脚本放 devDependencies 更合适。“声明范围”与“已安装版本”必须区分。^1.4.0 在部分符合语义化版本的版本区间内允许更新,它不是已安装版本。2.0.0 看起来固定,但若没有提交与之对应的锁文件,依赖的子节点变化仍应通过正式的安装结果复核。因此,门禁只做静态提示,不把写死的版本自动判定成整棵依赖树安全。项目的部署策略可以分成三个开关:是否允许范围版本、是否要求锁文件在版本控制中、是否允许本次变更触碰构建产物。这里只实现第一个最小环节,并提供另两个环节的人工检查路径。不要把一个字符串扫描器包装成供应链漏洞检测产品。## 二、把演示输入固定在最小文件里为了让输出可复核,准备一份符合 JSON 语法、同时也是 JSON5 合法子集的样例配置。它位于 entry/oh-package.json5。这是教学夹具,不代表可以直接安装的真实三方库。应用端有两个生产依赖样例,开发态还有一个脚本条目;门禁期望最终得到“2 项通过、1 项需复核”。json{ "name": "entry", "version": "1.0.0", "dependencies": { "@example/chart-ui": "^1.4.0", "@example/common-ui": "2.0.0" }, "devDependencies": { "@example/lint-rules": "1.0.0" }}第一条生产依赖采用范围版本,所以被标记为需复核;另外两条是显式固定字符串,在本轮静态规则下标记为通过。这里的“通过”仅指“未触发范围表达式检查”,绝不表示包可信、许可证已审查、漏洞已扫描或构建已成功。若项目启用了 dynamicDependencies,应另加检查;该字段用于特定动态 HSP 加载场景,不能当成普通运行依赖的替代品。实际的 oh-package.json5 可能包含注释、尾随逗号等 JSON5 特性。下面的最小脚本不会把 JSON.parse 冒充为通用 JSON5 解析器;当配置不在本 Demo 的 JSON 子集内时,它会明确报错并退出,而不是悄悄忽略字段。生产系统需要使用经过审查且适配目标工具链的 JSON5 解析方案,或直接借助 ohpm 支持的命令获取依赖信息。## 三、让检查器只说它确实知道的事这个工具的输入是样例 entry/oh-package.json5,输出是一个固定编号的报告。核心代码使用 Node.js 标准库,范围判断直接检测 ^、~、*,另外阻止一些容易被误读成固定版本的比较运算符。日志中用 stage=static, no-install 表示从未执行包安装,不要把它贴成 DevEco 编译成功截图。js// tools/check-deps.cjs:演示只接收JSON兼容的JSON5子集const fs = require('node:fs');const path = require('node:path');const file = path.join(process.cwd(), 'entry/oh-package.json5');let manifest;try { manifest = JSON.parse(fs.readFileSync(file, 'utf8'));} catch (err) { console.error('ERROR fixture is not JSON-compatible:', String(err)); process.exit(2);}const groups = [ ['production', manifest.dependencies ?? {}], ['development', manifest.devDependencies ?? {}]];let passed = 0, review = 0;console.log('DG-102 scope=entry');for (const [scope, deps] of groups) { for (const [name, spec] of Object.entries(deps)) { if (typeof spec !== 'string') { review++; continue; } const risky = /[\^~*<>|]/.test(spec); if (risky) review++; else passed++; console.log(`${risky ? 'WARN' : 'PASS'} ${name} ${spec} (${scope})`); }}console.log(`passed=${passed} review=${review}`);console.log('stage=static, no-install');process.exitCode = 0; // 仅展示报告:真实CI另行按review值阻断此处 process.exitCode=0 是演示用的报告模式:出现 WARN 时也允许脚本退出,方便 DevEco 预览读取结果,因此配图的 Exit code: 0 不代表依赖通过验证。真正接入 CI 时应根据 review > 0 设置非零退出码,让流水线阻断;不能把预览模式拿去当发布门禁。即使当前例子里能读到三条依赖,也不能据此断言所有间接依赖均已核对。遇到仓库中真实的 file: 路径、@module: 引用、动态 HSP 或可变标签,应把它们作为单独的审查分支,而不是用同一条正则作安全裁决。如果输出信息太多,可以先让脚本生成机器可读的结果摘要,再让 ArkUI 只呈现“通过、需复核、未检查”三种业务状态。不要让手机页面自己在运行时修改工程依赖:这类门禁属于开发和持续集成流程,不是终端用户要承担的配置工作。## 四、手机端只是报告阅读器,不是包管理器演示页面 ReportPage.ets 读取预置的报告摘要,并显示编号 DG-102、通过 2、需复核 1。界面标题为“依赖门禁”,按钮是“查看回滚清单”。图中时间 10:08 只是设计稿状态栏和开发视图的统一展示值,不能用于证明脚本实际运行时刻。下面的 ArkTS 片段表达报告展示的边界:它不调用 shell,也不通过网络下载依赖,仅把构建工具整理后的结果渲染出来。报告里那三个 @example/ 条目需要在正式应用中替换为由构建流水线真实生成、且经过校验的数据。ts@Entry@Componentstruct ReportPage { @State reportId: string = 'DG-102'; @State passed: number = 2; @State review: number = 1; build() { Column({ space: 18 }) { Text('依赖门禁').fontSize(26).fontWeight(FontWeight.Bold); Text(`检测报告 ${this.reportId}`).fontSize(20); Text('仅静态检查 · 未执行安装'); Row({ space: 20 }) { Text(`${this.passed} 通过`); Text(`${this.review} 需复核`); } Text('@example/chart-ui ^1.4.0 需复核'); Text('@example/common-ui 2.0.0 通过'); Text('开发态脚本 1 项 通过'); Button('查看回滚清单'); } .padding(20).width('100%'); }}此处按钮只是界面示意;如要真正点击打开清单,必须再补充路由和已审核的清单数据源。文章不把尚未实现的点击功能描述为“已可操作”。移动端截图展示的就是这一静态报告阅读状态:2 通过、1 需复核,没有出现安装成功或发布成功的结论。## 五、回滚清单要指向锁文件,而不是猜测旧版本门禁发现 ^1.4.0 后,不应自动把它改成“可能最安全”的某个补丁版本。真正可审查的操作顺序是:先确认团队允许的版本区间,再查看当前被提交的锁文件变更;若版本更新已纳入计划,在独立分支执行受控的 ohpm install 或相应更新操作,核对实际解析树和受影响的构建任务。锁文件只能由包管理工具维护,而不是让 Node 脚本拼接文本去覆盖。ohpm list 可以用于查看已安装依赖关系,但那是另一阶段的证据。脚本当前根本没有运行它,所以报告不能包含“已确认传递依赖版本一致”的结论。对异常回滚,最稳妥的是恢复经过团队验证的清单与锁文件提交,然后重新安装并跑构建、回归测试;不能在某台机器的缓存目录里删几个包就称之为可追溯回滚。还需要区别异常类型:下载失败属于网络或镜像问题;版本冲突属于依赖解析问题;API 不兼容属于编译与运行问题;发布拦截还涉及签名和应用审核规则。它们可能在一天内连续出现,但不应该都塞进“版本漂移”这一故障原因。工具只给出当前能证明的事实,才方便后续扩展。## 六、哪些情况下这道门禁有价值它适合多模块应用、多人协作或固定分支的发布流水线,尤其是代码 diff 中经常遗漏配置文件变动的团队。可实施的首轮规则只有三条:生产依赖范围声明是否被允许;新增依赖是否进入对应模块配置;相关锁文件是否有受控变更。日志和审核意见最好附上模块名、依赖名与具体声明值,避免只写一个“依赖异常”。它不适合代替许可证合规审查,也不负责漏洞情报、包完整性签名或运行时兼容性。尚未经过实际安装和构建的样例,也不能宣称兼容某个指定 DevEco Studio 小版本。本示例的重点在于把“脚本检查结果”“包管理器解析结果”“工程真实构建结果”拆开表达:门禁可以提前发现风险,但不能替后面的验证阶段签字。官方参考:- 华为:oh-package.json5 配置说明- 华为:添加依赖项- 华为:ohpm update 行为说明:以上包名、报告编号、日志和 UI 截图均为离线演示样例;未执行真实 ohpm 安装、编译或真机测试。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐