@nianzixin/harmony-code-locator
v0.1.5
Published
HarmonyOS ArkUI screenshot-to-source locator for debug builds.
Downloads
892
Maintainers
Readme
Harmony Code Locator
Harmony Code Locator 是 Compose Code Locator 思路在 HarmonyOS / ArkUI 上的工程化探索:在不改业务代码的前提下,通过 Hvigor 构建期扫描 ArkTS UI 调用点,生成稳定 source index,并在 debug 构建中注入私有 source identity,供 IDE 插件做“截图点击 -> 源码跳转”。
ArkTS / ArkUI source
-> Hvigor scan / transform
-> sourceId -> file:line shard index
-> debug-only .id("__hmloc_<sourceId>")
-> UIContext Inspector Tree + ComponentUtils bounds
-> IDE hit-test -> sourceId -> file:line当前能力
- 扫描
src/main/ets/**/*.ets中的 ArkUI 系统组件调用点。 - 自动发现项目内
@Component/@ComponentV2 struct,覆盖业务自定义组件边界。 - 对可安全注入的组件追加私有
.id("__hmloc_<sourceId>")。 - HAP 模块可在 debug 构建期自动给
UIAbility注入HmLocatorDebugBridge启动代码,构建结束后恢复,不需要业务源码手写启动逻辑。 - 遇到已有业务
.id(...)时跳过,不覆盖、不改变业务语义,并在报告中记录existing-id。 - 生成面向大项目的分片索引:
studio-index/v1/source-id-index.tsv+shards/*.jsonl,避免单个超大 JSON。 - Runtime 从当前
UIContext.getFilteredInspectorTree(['id'])的轻量实例树读取$ID/$rect/$type,同一个源码调用点在ForEach/LazyForEach中产生的多个 item 会保留为多个独立运行时实例,同时共享稳定 sourceId。 hitTest会保留 Inspector Tree 的 depth/order,优先命中顶层窗口中的更深叶子节点,再比较 bounds 面积,减少点击子控件却跳到大父容器的问题。- DevEco Studio 只高亮并打开排序后的首个可导航候选,支持浮点 bounds,不再让祖先容器框覆盖实际子控件选择框。
- DevEco Studio 插件支持截图 Fit、放大、缩小和 100% 显示,Pad / 手机截图都可以通过滚动区域查看和点击定位。
CLI
node bin/hm-locator.js --version
node bin/hm-locator.js scan \
--project /path/to/HarmonyProject \
--out /tmp/hm-locator-out
node bin/hm-locator.js verify \
--project /path/to/HarmonyProject \
--out /tmp/hm-locator-out
node bin/hm-locator.js workspace-verify \
--project /path/to/HarmonyWorkspace \
--out /tmp/hm-locator-out
node bin/hm-locator.js workspace-scan \
--project /path/to/HarmonyWorkspace \
--out /tmp/hm-locator-out \
--source-roots src/main/ets,src/custom/ets \
--exclude-module-dirs vendor,generated
node bin/hm-locator.js workspace-patch \
--project /path/to/HarmonyWorkspace \
--out /path/to/HarmonyWorkspace/build/hm-locator
node bin/hm-locator.js workspace-restore \
--project /path/to/HarmonyWorkspace \
--out /path/to/HarmonyWorkspace/build/hm-locator
node bin/hm-locator.js workspace-integrate \
--project /path/to/HarmonyWorkspace \
--dry-run \
--report-out /tmp/hm-locator-integrate-dry-run.json
node bin/hm-locator.js workspace-integrate \
--project /path/to/HarmonyWorkspace \
--locator-package-spec 0.1.5 \
--source-roots src/main/ets,src/custom/ets \
--exclude-module-dirs vendor,generated
node bin/hm-locator.js verify-release \
--project /path/to/HarmonyWorkspace \
--report-out /tmp/hm-locator-release-gate.json
node bin/hm-locator.js doctor \
--project /path/to/HarmonyWorkspace \
--report-out /tmp/hm-locator-doctor.json
node bin/hm-locator.js devices
node bin/hm-locator.js device-smoke \
--project /path/to/HarmonyWorkspace \
--x 120 \
--y 240 \
--report-out /tmp/hm-locator-device-smoke.json
node bin/hm-locator.js device-matrix \
--project /path/to/HarmonyWorkspace \
--x 120 \
--y 240 \
--report-out /tmp/hm-locator-device-matrix.json输出结构:
hm-locator-report.json
studio-index/v1/
manifest.json
source-id-index.tsv
shards/<hex>.jsonl
transformed-src/ # verify / transform only
modules/<module>/ # workspace commands only报告字段:
recognizedEntries: 识别到的 ArkUI/source boundary 总数。locatableEntries: 已生成私有 locator id、可被 runtime 定位的数量。skippedEntries: 出于安全原因未注入的数量。skippedByReason.existing-id: 原组件已有业务.id(...),当前不会覆盖。customComponents: 自动发现的业务 ArkUI 组件名。
doctor 会检查本机 Node、DevEco Hvigor、hdc、SDK 根目录和工程 build-profile.json5,用于提前发现 TransformStream is not defined、SDK 组件缺失、HarmonyOS/OpenHarmony SDK 不匹配等接入问题。
doctor / workspace-integrate / verify-release / devices / device-smoke / device-matrix 都支持 --report-out <json>,便于团队 CI 归档机器可读的环境诊断、接入 dry-run、release gate、HDC 状态、截图、runtime health、hit-test 和源码解析结果。
devices 只检查 HDC target 状态,不连接 app runtime。它会列出 Connected / Ready / Offline / Unauthorized,并给出授权、重连或启动模拟器建议。建议在真机 smoke 之前先跑它,把设备连接问题和 runtime 问题分开。
device-smoke 用于单设备闭环验收:枚举 HDC target、建立 tcp:<localPort> -> tcp:49392 转发、抓取截图、调用 runtime health/snapshot/hitTest,并通过本地 studio-index/v1 解析命中的 sourceId -> file:line。若 HDC 枚举卡住,可单独加 --hdc-timeout 10000。
device-matrix 会对所有在线 HDC target 逐台运行同样的 smoke 流程,并给每台设备分配不冲突的本地转发端口。它适合真机矩阵回归,尤其是同时连接手机、Pad、模拟器时。
workspace-integrate 会自动完成构建层接入:
- 根
hvigor/hvigor-config.json5添加@nianzixin/harmony-code-locatornpm dependency。 - 每个 hap / har / hsp 模块
hvigorfile.ts添加对应hapPlugin/harPlugin/hspPlugin。 - 复制
runtime-har到工程根hm-locator-runtime。 - hap 模块
hapPlugin默认增加patchRuntimeBridge: true,debug 构建时自动 patchUIAbility启动 bridge。
默认不永久修改 entry/hap 模块 oh-package.json5 的 @hm-locator/runtime 依赖,避免 release 包长期携带 debug runtime。patchRuntimeBridge: true 会在 debug patch 阶段给实际注入了 UIAbility bridge 的 HAP 模块临时生成 src/main/ets/hmlocator/* runtime 源码,并把 Ability import 改成相对路径;同时会在 Hvigor 编译/打包中间 profile 里临时补 ohos.permission.INTERNET,让 TCP loopback debug server 通过 ArkTS 权限校验。buildFinished 后源码和 Ability patch 一起恢复/删除。若需要快速固定依赖做本地实验,可显式加 --add-runtime-dependency,但这不是默认构建接入路径。
verify-release 会检查业务源码和依赖文件中是否残留 __hmloc_、HmLocatorDebugBridge 或 @hm-locator/runtime。建议在 release 打包前加入门禁。
默认接入会写入 file:<当前 harmony-code-locator 路径>,适合本地试验。npm 发布后,可用 --locator-package-spec 0.1.5 写入正式版本依赖。如果团队工程使用了非标准 ArkTS 源码目录,可用 --source-roots src/main/ets,src/custom/ets 写入每个模块的插件配置;同一个参数也适用于 scan / verify / patch / workspace-scan / workspace-verify / workspace-patch。大型 workspace 接入、手动扫描或 patch 时,可以用 --exclude-module-dirs vendor,generated 跳过不需要参与定位的目录,避免第三方、生成代码或 sample 模块被自动改写。workspace-integrate 是幂等的,重复执行不会重复插入插件或依赖。建议先用 --dry-run 查看将修改哪些文件,再对工作区副本或已提交干净的工程执行真实接入。
Hvigor 插件形态
插件形态参考 TheRouter Harmony 的工程方式:以 npm 包导出 hapPlugin / harPlugin / hspPlugin,在每个 hap / har / hsp 模块的 hvigorfile.ts 中启用。插件会先收集模块,等 hvigor.nodesEvaluated() 后再为每个 target 注册任务,并在 hvigor.buildFinished() 中统一恢复源码 patch。
import { hapPlugin } from '@nianzixin/harmony-code-locator';
export default {
plugins: [
hapPlugin({
enabled: true,
workspaceRoot: '../..',
patchSources: true,
patchRuntimeBridge: true,
debugOnly: true
})
]
}默认建议使用 patchSources: true 作为 debug 编译接入路径:PreBuild 后备份并原地注入 .id("__hmloc_<sourceId>"),MergeProfile 前进入编译链,构建结束后恢复原始源码。transform: true 只建议用于离线验证,它会输出 transformed source mirror,不参与真实编译。
多模块项目建议显式配置 workspaceRoot,这样每个模块的 sourceId 都以仓库根路径生成,IDE 侧可以消费统一的 merged index。
debugOnly 默认等价于 true。构建模式名包含 debug / dev / test 时才会执行源码 patch;release 构建会生成跳过报告,不改源码。特殊团队构建模式可以显式配置:
hapPlugin({
workspaceRoot: '../..',
patchSources: true,
enabledBuildModes: ['phoneDebug', 'padDebug']
})每个模块会生成 source-patch/manifest.json 记录原始 hash 和 patch hash;如果构建中断,可手工执行 workspace-restore 恢复。若构建期间源码被外部修改,restore 会报告 conflict 并拒绝覆盖,避免误丢业务改动。
Runtime
runtime-har/ 是可放入业务工程的 debug-only HAR 模块模板;runtime/ 保留同源运行时代码,便于直接查看或复制。接入方式见 docs/runtime-har.md。通过 workspace-integrate 接入时,HAP 模块会默认启用 patchRuntimeBridge: true,Ability 启动代码和 runtime 依赖都会在 debug 构建期自动注入并恢复。
核心策略:
- App 侧不需要携带完整
sourceId -> file:line大表,sourceId已编码在私有 id 中。 - App 侧只返回当前屏幕命中的
sourceId + bounds。 - IDE 侧读取本地构建产物
studio-index/v1,完成sourceId -> file:line跳转。 - App 与 IDE 默认使用 TCP loopback + JSON-lines 协议,App 监听
127.0.0.1:49392,IDE/HDC 转发到本机临时端口,见docs/protocol.md。 - IDE 侧索引解析、HDC 转发和客户端接入边界见
docs/ide-integration.md。 - Hvigor 真实构建验证命令和本机 SDK 注意事项见
docs/hvigor-validation.md。 MultiShoppingPriceComparison-master的具体接入步骤见docs/multishopping-sample.md。- 团队级试点、CI 门禁和发布检查清单见
docs/team-rollout.md。 - npm 发布流程见
docs/npm-publishing.md。 - DevEco Studio 插件边界和构建方式见
docs/ide-integration.md。
npm 发布前本地门禁:
npm run verify:publish
npm pack --dry-runverify:publish 会串起单元测试、真实 npm tarball 消费者安装 smoke、CI JSON 报告生成;prepublishOnly 也绑定到同一门禁,避免直接 npm publish 时绕过检查。
这种拆分对大项目更友好:编译期索引留在本地 build 目录,运行时只处理当前 UI 树可见节点,包体积和运行时开销都可控。
样例验证
在 MultiShoppingPriceComparison-master 上验证结果:
Discovered 7 Harmony modules.
Recognized 443 ArkUI source identities.
Locatable 437; skipped 6.
Injected 437 locator ids across 7 modules.6 个跳过项均为已有业务 .id(...) 的 Navigation 节点。
真实 Hvigor debug 构建也已在样例工程副本上验证通过,构建输出为:
build/outputs/default/MultiShoppingPriceComparison-master-default-unsigned.app构建结束后已验证业务源码和 oh-package.json5 无 __hmloc_、HmLocatorDebugBridge、@hm-locator/runtime 残留。
2026-07-16 最新本地验证:
workspace-integrate --dry-run: 7 modules, changedFiles=0
verify-release: checkedFiles=199, violations=0
device-smoke: emulator 127.0.0.1:5555, screenshot=2210x2416 jpeg
device-smoke: Health OK windowCount=1, Snapshot OK nodeCount=69
device-smoke: HitTest OK candidates=10
device-smoke: Resolved common/multishoppingbase/src/main/ets/view/HomeHeader.ets:51:9 ListItem
device-matrix: onlineTargets=1, passed=1 failed=0后续工程化
@nianzixin/[email protected]发布后可通过 npm + Hvigor 接入 Harmony 工程。- DevEco Studio 可视化插件已作为独立
deveco-plugin子项目交付;Gradle 只用于构建 IDE 插件 ZIP,不参与 Harmony App/Hvigor 构建,也不会进入 npm 包。CI artifact / GitHub Release 中的harmony-code-locator-deveco-<version>.zip可用于 DevEco Studio 本地安装。 - 用真实 HarmonyOS/OpenHarmony 设备验证 HDC 连接、抓屏、hit-test、源码解析闭环;模拟器已验证通过,CLI 已提供
snapshot_displayjpeg/png/legacy fallback,但仍需要覆盖更多厂商设备。 - 做真机矩阵回归:多 Ability、多窗口、Dialog、Dropdown、Popup、半屏、Navigation 栈。源码注入层已有这些高频 ArkUI 调用点的自动回归,真机回归重点是窗口层级和坐标命中。
