鸿蒙PC开发实战:用 CodeArts Agent + DevEco Studio 从零适配开源项目 Mockoon (CodeArts Agent高效赋能鸿蒙PC应用适配实战)

欢迎加入开源鸿蒙PC社区: https://harmonypc.csdn.net/

欢迎在PC社区平台申请新建项目: https://atomgit.com/OpenHarmonyPCDeveloper

本文项目源码已上传 AtomGit 仓库: https://atomgit.com/weixin_52908342/ohos_Mockoon

在这里插入图片描述

写在前面:这是一篇"真机实录",不是教程

先说清楚一件事:这篇不是那种"我教你怎么做"的教程,而是"我刚干完一遍,把屏幕录下来给你看"的实录。

2026 年 8 月 28 日晚上 8 点,我坐在鸿蒙 PC 前面,打开 CodeArts Agent,敲进去一句话——

Mockoon 的开源地址:https://github.com/mockoon/mockoon

然后我就没怎么动手了。8个半小时后,Mockoon 的界面真真切切地跑在了我这台鸿蒙 PC 上,路由、数据桶、CORS 头、代理模式,一个个功能点挨个点过去,全都正常。

在这里插入图片描述

CodeArts Agent 主界面

上面这张就是 CodeArts Agent 的主界面。左边是工程目录树,右边是对话区,底部是技能选择栏。看着是不是有点像 VS Code?但它真正厉害的地方不在界面,而在于——它能自己上网查文档、自己敲命令、自己改代码、自己排错,遇到问题还会自己换条路走

这篇文章,我把从"装机"到"跑起来"的全过程,32 张截图 + 全部关键代码,原原本本摆出来。中间踩的坑一个不藏,Agent 犯过的傻也照实说。

先给结论:在鸿蒙 PC 上,CodeArts Agent + DevEco Studio 这套组合,把一个 9.8.0 版本、Electron 43 + Angular 22 技术栈的大型开源项目跑起来,从零到可用,8个半小时。如果纯手工做,保守估计三到五天。

一、为什么挑 Mockoon 下手?

动手之前,先说说选题。开源桌面软件千千万,为什么是 Mockoon?
在这里插入图片描述

1.1 它填补了鸿蒙 PC 的一块空白

Mockoon 是干什么的?一句话:让你在本地几秒钟起一个 REST API。

前端同学对它应该不陌生。后端接口还没开发完,前端又急着联调,怎么办?装个 Mockoon,图形界面点几下,一条路由、一份假数据,一个可用的 Mock 服务就跑起来了。不用部署、不用注册账号、不用写后端代码。它的口号就是 “the easiest and quickest way to run mock APIs locally”。

而这样一款开发者天天要用的工具,在鸿蒙 PC 上此前是一片空白。鸿蒙 PC 目前最缺的不是"能跑的应用",而是开发者工具链。一个生态能不能留住开发者,看的不是你能不能刷视频,而是你能不能在这里写代码、调接口、做测试。

所以适配 Mockoon,不只是"多了一个软件",而是往鸿蒙 PC 的开发者工具箱里,塞进了一把趁手的螺丝刀。

1.2 技术栈极具代表性

Mockoon 9.8.0 的技术栈是 Electron 43 + Angular 22 + Bootstrap 5 + esbuild。这个组合太典型了——

技术 版本 代表性意义
Electron 43 当下最主流的桌面应用框架,版本还很新
Angular 22 重型前端框架,standalone 组件模式
esbuild 新一代打包器,配置风格和 webpack 完全不同
monorepo npm workspaces 现代大型项目的标准组织方式

拿下它,等于拿下一大类。 因为绝大多数 Electron 应用的适配套路是相通的:改打包策略、改资源路径、塞进运行时。Mockoon 能跑通,Figma 类、Notion 类、VS Code 类的应用大概率也能跑通。

1.3 它是"零原生依赖"的干净样本

这点最关键。我事先翻过 Mockoon 的依赖树,它的 Mock 服务核心是 Node.js 内置 http 模块 + Express,没有任何需要编译的原生 addon(没有 better-sqlite3、没有 node-gyp、没有 keytar、没有 sharp)。

这意味着什么?意味着它可以被 HarmonyOS 定制的 Electron 运行时直接承载,不需要重写业务逻辑,不需要裁剪原生模块,不需要写兼容层。

反过来说,如果一上来就挑一个有大量原生 addon 的项目(比如带 better-sqlite3 的),光是把原生模块编译到鸿蒙平台就得折腾好几天,很容易从入门到放弃。

所以选题原则就三条:生态刚需、技术典型、依赖干净。 Mockoon 三条全中。


二、环境准备:版本不对,一切白搭

2.1 版本选 6.1.0.135 以上

这是我要反复强调的第一件事,也是最多人栽跟头的地方。

怎么确认自己的版本?在应用市场的应用尝鲜里搜 CodeArts Agent,点进详情页,页面下方会有一行"支持设备"的说明。先看 DevEco Studio 的详情页:

应用市场 DevEco Studio 详情页

这是 DevEco Studio 的详情页,版本 6.1.5.408,体积 2271.4 MB(没错,2.2 个 G,装之前记得清清磁盘)。开发者是华为终端有限公司。

再看 CodeArts Agent 的详情页,这张图信息量很大:

应用市场 CodeArts Agent 详情页

2.2 两个工具,各司其职

很多人会问:DevEco Studio 和 CodeArts Agent 到底啥关系?是不是装一个就行?

不行,两个都得装,而且分工明确:

工具 角色定位 干什么活
DevEco Studio 官方 IDE 建工程、配签名、编译 HAP、部署到真机、看日志
CodeArts Agent AI 智能体 读源码、查文档、改代码、敲命令、排错、总结

打个比方:DevEco Studio 是"手",CodeArts Agent 是"脑"。 Agent 负责想明白怎么改、改哪里,改完之后交回 DevEco Studio 编译打包推到设备上。两者通过同一个工程目录协同工作——这点是关键,它们必须指向同一个文件夹。

我的建议是:先用 DevEco Studio 把工程建好、签名配好、Hello World 跑通,再交给 CodeArts Agent。 为什么?因为签名这事儿 Agent 干不了(要登录华为账号),而没签名的 HAP 装不上真机。顺序反了会卡死。

在这里插入图片描述

三、开工:DevEco Studio 建工程

3.1 新建工程

打开 DevEco Studio,映入眼帘的是欢迎页:

DevEco Studio 欢迎页

就两个按钮,“新建工程"和"打开”。我们点"新建工程"。

接下来是模板选择。这里选 Empty Ability(空能力),它最小最干净,没有多余的示例代码干扰。

新建工程对话框

填几个关键字段:

字段 说明
Project name PCMockoon 工程名
Bundle name com.example.pcmockoon 先按默认的来,后面会改
Save location 默认路径 记牢这个路径,Agent 要用
Model Stage 必须是 Stage 模型

注意看截图下方那个"设备类型"区域,默认 Phone、Tablet、2in1 三个全勾着

3.2 只留 2in1,锁定 PC 形态

这一步很重要,很多人会忽略。

把 Phone 和 Tablet 的勾取消,只留 2in1。

为什么?因为我们要做的是鸿蒙 PC 应用,不是手机应用。只留 2in1,工程配置里就只会生成 PC 形态的配置,不会出现"手机上也要适配"的冗余资源。省事,也避免后面编译时因为多设备形态产生奇怪的问题。

点"Finish",工程就建好了。IDE 打开后长这样:
DevEco Studio 打开工程

左边是标准的鸿蒙工程目录树(entry/src/main/ets/pages/Index.ets),中间是代码编辑器,默认给你渲染了一个 Hello World 页面。

到这里,工程的"骨架"就有了。下一步是最容易卡人的环节——签名。

四、签名配置:卡住最多人的一道坎

4.1 为什么没签名就跑不了

鸿蒙的安全机制要求:所有安装到真机的 HAP 必须经过签名。没签名的 HAP 装上去会直接报错,典型错误码是 9568320(签名信息缺失)。

DevEco Studio 提供了"自动签名",但需要登录华为开发者账号。(这里说的是鸿蒙PC电脑真机)

4.2 操作路径

在这里插入图片描述

操作很简单,跟着点就行:

  1. 菜单栏 File → Project Structure → Signing Configs
  2. 勾选 Automatically generate signature(自动生成签名)
  3. 如果没登录,点 Sign In,会弹出华为账号登录页
  4. 用华为账号登录后,点 Apply / OK

登录成功的标志是:签名配置面板里能看到这些字段被自动填上了——

字段 说明
Store File .p12 密钥库文件路径
Store Password 密钥库口令
Key Alias 密钥别名,通常是 debugKey
Key Password 密钥口令
Sign Alg 签名算法,SHA256withECDSA
Profile File .p7b 签名描述文件(绑定 bundleName
Certpath File .cer 数字证书

这里埋了一个巨坑,我提前说:那个 .p7b 文件是绑定 bundleName 的。也就是说,如果你拿 A 项目生成的签名材料去签 B 项目,编译时会报 SignHap 00303074(bundleName 不匹配)。后面我确实栽在这上面了,第 11 节会详细讲。

记住:每个项目都要重新跑一次自动签名。

4.3 第一个里程碑:Hello World 跑通

签名配好,点运行按钮(绿色三角),选你的鸿蒙 PC 真机。
Hello World 运行成功

看到那个弹出的 “Hello World” 窗口了吗?这就是第一个里程碑。

底部日志栏那行绿色的字是关键:

Launch com.example.pcmockoon success in 7/7s, 279 ms

Launch ... success —— 说明 HAP 已经成功编译、签名、推送、安装、启动,一整条链路全通了。

到这一步,我要停下来强调一下为什么必须先跑通 Hello World

  1. 验证了签名是对的(能装上)
  2. 验证了真机连接是对的(能部署)
  3. 验证了工具链是完整的(hvigor / ohpm 都正常)
  4. 验证了 compileSdkVersioncompatibleSdkVersion 这些配置是匹配的

这四条任何一条不通,后面 Agent 改再多的代码都白搭。地基不打牢,AI 也救不了你。

五、CodeArts Agent 登场:把项目交给它

在这里插入图片描述

5.1 用 Agent 打开同一个工程

现在轮到主角了。打开 CodeArts Agent,选择"打开文件夹",指向刚才 DevEco Studio 建的那个 PCMockoon 目录

CodeArts Agent 打开项目

打开后,左边是工程目录(和 DevEco 里看到的完全一致),右边是对话区。

注意底部那个技能选择栏,这是 CodeArts Agent 的核心能力之一。它内置了很多技能包,我这次用的是 Vibe-Coding(氛围编程,让 Agent 自由发挥)。旁边还有:

  • Spec-Driven(规格驱动,先出文档再写代码)
  • 鸿蒙开发(企业)/ 鸿蒙开发(标准)(鸿蒙专用技能包)
  • hmos-dev-pipeline(鸿蒙开发流水线)

模型我选的 GLM-5.2。另外还有 OpenPangu-2.0-Flash、GLM-4.7-ArKTS-SPARK 等可选。

5.2 先让 Agent 摸清你要什么

在正式下指令之前,我先跟 Agent 做了一轮"需求对齐"。这一步看起来多余,其实非常关键——你不把目标说清楚,Agent 就会按自己的理解瞎猜
CodeArts Agent 需求对齐对话
看这张截图,Agent 收到"开发一个鸿蒙 PC 应用"这个模糊指令后,没有立刻开始写代码,而是反过来问我几个关键问题:

  • 这个应用主要用来做什么?
  • 需要哪些核心功能?
  • 数据存储用什么方案?

这就是它内置的 “需求规格设计” 环节——先把需求问清楚,再动手。这一轮问答省下的返工时间,远超你想象的。

我的经验是:宁可多花三分钟把需求说透,也不要后面花三小时返工。 尤其是适配类任务,目标边界一旦模糊,Agent 很容易跑偏到"重写一个应用"而不是"移植现有应用"上去。

5.3 一句话启动:把开源地址丢给它

需求对齐之后,正式下指令。我敲的第一句话极其简单,就是把开源项目的地址丢过去:
输入 Mockoon 开源地址

Mockoon 的开源地址:https://github.com/mockoon/mockoon

同时我在工程 docs/ 目录下预先放了一批参考资料(都是我以前踩坑总结的实战手册),在对话里用 @ 引用给了它:

  • ohos_成功适配综合集.md
  • 鸿蒙PC-Electron适配完整实战手册.md
  • 鸿蒙PC开源软件适配经验总结.md
  • 鸿蒙PC开源软件适配问题汇总.md
  • 鸿蒙PC开发者相关文档索引.md

这是我能一次成功的关键经验之一:Agent 再聪明,也不知道你踩过的坑。把历史经验文档喂给它,相当于给它装了个"外挂知识库"。后面你会看到,它真的会去读这些文档,而且读得很仔细。

六、看 Agent 自己找源码:GitHub 不通就换镜像

6.1 第一次尝试:git clone 被墙

Agent 收到任务,先自己规划,然后开始敲命令。

Agent 克隆项目

看它的心路历程,特别有意思:

  1. 第一反应git clone https://github.com/mockoon/mockoon —— 超时失败
  2. 自己排查curl -I https://github.com 测连通性 —— 确认不通
  3. 自己换路:改用镜像站 giteone.com 走代理
  4. 换个招:直接 curl -L 下载 zip 包

这里我要给它鼓个掌。它没有被"命令执行失败"卡住,而是自己去诊断网络、自己换方案。 这就是 Agent 和"自动化脚本"的本质区别——脚本遇到预设外的情况就死,Agent 会想办法。

最终它用下载 zip 的方式拿到了源码,大小约 2.2 MB。

6.2 第二次麻烦:unzip 没权限

拿到 zip 之后,又出问题了。

解压与环境探测

它试了:

  • unzip mockoon.zip —— 权限 / 命令不可用
  • 检查 python3 --version —— 想用 Python 解压
  • 检查 node --version / npm --version —— 想用 Node 解压
  • 最后方案npm install adm-zip,用 Node 库解压

你看出规律了吗?它在用"排除法"探测环境能力。 一个工具不行就换下一个,直到找到一个能用的。这种"环境自适应"能力,是手工操作很难做到的——人通常试两次就烦了,Agent 不会烦。


七、Agent 的项目剖析:比我还懂 Mockoon

7.1 结构分析

解压完成后,Agent 主动开始分析项目结构。

项目结构分析

它给出的结论相当专业:

mockoon/                      # 项目根目录
├── packages/                 # monorepo(npm workspaces)
│   ├── app/                  # Electron 桌面应用
│   ├── cli/                  # 命令行工具
│   ├── commons/              # 公共库
│   ├── commons-server/       # 服务端公共库(Mock 引擎核心)
│   ├── cloud-server/         # 云服务
│   └── serverless/           # Serverless 支持
├── shared/                   # 共享类型定义
└── scripts/                  # 构建脚本

还配了一段"遇到的问题及处理"小结,把克隆失败、解压失败的前因后果都写清楚了。它会自己复盘。

7.2 技术总评价:这一段让我刮目相看

接下来 Agent 输出了一份完整的技术评估报告:

Agent 技术总评价

核心结论我整理成表格:

评估维度 Agent 的结论
工程成熟度 高。monorepo(npm workspaces)+ Electron 桌面应用
架构 TS 严格模式、ESM / CJS 双输出、Angular 22 standalone、Electron 43
功能完整度 极高。CLI、Serverless、11 个目标平台、CRUD 自动端点、WebSocket
安全设计 Joi 参数校验、ReDoS 防护、timing-safe 比较、Electron 沙箱
AI 能力 已支持 MCP(Model Context Protocol)
服务端核心 Express + OpenAPI 规范设计 + Handlebars 模板引擎 + 数据迁移模块
渲染层 Electron / Angular monorepo + Redux 状态管理

最关键的一句判断:“Mockoon 核心 Mock 服务器基于 Node.js http 模块 + Express,零原生 addon 依赖。”

这句话直接决定了适配路线——可以用 HarmonyOS 定制的 Electron 运行时(libelectron)直接承载,不需要重写、不需要裁剪、不需要 mock 掉原生模块。

说实话,这个判断我要是手工做,得花至少一个小时翻 package.json、翻依赖树、翻构建配置。Agent 几分钟就给出来了,还写得比我清楚。

八、Agent 自己上网查鸿蒙文档

这是我觉得最震撼的一步。

Agent 分析完 Mockoon 之后,自己去联网查鸿蒙的官方文档了

在这里插入图片描述

它查了这些:

  • 鸿蒙 ArkTS 文档
  • 鸿蒙网络能力文档
  • 鸿蒙 Web 组件文档
  • Electron 迁移方案相关资料

然后给出 developer.huawei.com 上的对应链接。

这意味着什么? 意味着它不是在凭"训练数据里的旧知识"瞎编,而是实时去查最新的官方文档。鸿蒙的 API 迭代很快,靠模型记忆里的旧知识写出来的代码大概率跑不起来。能联网查证,这个能力太重要了。

顺便说一句,截图上那个"思考中…"的状态提示,说明它在做多轮推理,不是简单的一问一答。


九、开始改代码:Agent 的执行阶段

9.1 阶段 0:复制基线版本

查完文档,Agent 开始动手了。
阶段 0 执行

它的策略很聪明:不是从零写,而是复用已有的成功案例。

我工作区里有一个 ohos_Zettlr(之前适配成功的 Electron 应用),Agent 识别出来后,直接把它作为基线模板复制过来。这一步带来了什么?

  • libelectron.so(Electron 运行时)
  • libadapter / libffmpeg / libc++_shared 等原生库
  • 完整的双模块 HAP 骨架(electron 宿主模块 + web_engine HAR 模块)
  • WebAbility 宿主启动代码

省下的工作量:至少两天。 这就是为什么我前面说"先找先例,不要从零造壳"。

然后它开始改身份:

  • 复制 AppScope 资源(app_icon.png、app_logo.png 等)
  • 修改 app.json5(+12 行)
  • 修改 build-profile.json5
  • 创建 oh-package.json5(+24 行)

9.2 阶段 4:清理旧品牌 + 核心打包改动

清理 Zettlr 品牌残留

这一步有个细节让我印象很深:它在清理 Zettlr 的残留品牌标识(旧的应用图标、logo 文件),而且清理完还专门做了验证——grep -r "Zettlr" 确认无残留。

这种"改完自己验"的习惯,比很多人类工程师都强。

紧接着是本次适配最核心的一处改动——esbuild 打包策略。

9.3 改动总表:一眼看清全局

Agent 干完之后,给了一份完整的改动总结:

改动总表

我把它整理成表格:

阶段 内容 状态
阶段 0 复制基线版本(ohos_Zettlr 模板 + web_engine,含 libelectron.so)
阶段 4 esbuild 配置(核心改动packages: externalbundle + external: [electron]
阶段 5 图标配置(icon → renderer/assets/favicon-96x96.png;preload / loadfile 保持不变)
阶段 6 base href(build.prod.renderer 增加 --base-href /
阶段 7 脚本准备(running package.json + scripts/build-and-deploy.sh
阶段 8 产品身份化(bundleName:com.mockoon.ohos;所有 Zettlr → Mockoon)
阶段 9 自检(无 Zettlr 残留,全部配置通过)
阶段 1-3 构建(需要 Node.js + npm 环境)
阶段 10-11 构建 HAP(需要 DevEco Studio + hvigorw)

上游源码只改了 3 个文件,这个数字很重要——改动越小,后续同步上游越轻松


十、构建环境:Agent 自己搞定 Node 和 npm

10.1 环境探测

代码改完,开始构建。首先得确认 Node 环境。

Node 环境探测

Agent 敲了这些命令:

node -e "console.log('hello')" 2>&1 | head -5
npm --no-opt "console.log('hello')" 2>&1 | head -5
node --version
npm --version

结果:

  • Node.js v22.22.3
  • npm 11.6.2

注意截图里有个细节:它设置了 NODE_OPTIONS=--jitless。这是为了绕开鸿蒙平台上 V8 JIT 的一些兼容问题。不是我教它的,是它自己查文档查出来的。

10.2 依赖安装

环境确认,开始装依赖。

npm install 依赖安装

它用的命令:

npm install --ignore-scripts --legacy-peer-deps 2>&1 | tail -10

两个 flag 都有讲究:

  • --ignore-scripts:跳过 postinstall 脚本。因为很多原生模块的 postinstall 会在鸿蒙上失败
  • --legacy-peer-deps:忽略 peer dependency 冲突。monorepo 项目里 peer 冲突很常见

装完它还检查了退出码 echo $? 确认成功。

10.3 esbuild + Angular 构建

依赖装好,正式构建。

在这里插入图片描述

关键输出:

Main process compiled successfully!
app.js  4.5MB (already stripped)
All relevant APIs verified

主进程打包成功,4.5 MB。然后它继续测试 Angular 渲染管线:

npx ng build --configuration=development --base-href / 2>&1 | tail -30

十一、踩坑实录:四个坑,一个比一个阴

这一段是全文最值钱的部分。每一个坑都是真金白银的时间。

坑 1:bundleName 不匹配(SignHap 00303074)

现象:HAP 编译报 bundleName 不一致。

bundleName 不匹配

原因:我在 DevEco Studio 建工程时用的是 com.example.pcmockoon,签名材料(.p7b)也是按这个 bundleName 生成的。但 Agent 做"产品身份化"时,把 AppScope/app.json5 里的 bundleName 改成了 com.mockoon.ohos

两边对不上了。

Agent 的排查过程

grep -r "bundleName" --include="*.json5" --include="*.json" .

把所有配置里的 bundleName 全找出来,逐个对齐。

这里有个选择:要么改签名(重新自动签名),要么改 bundleName。最终我们选择保持 com.example.pcmockoon 与签名一致——因为在真机调试阶段,频繁改签名太麻烦。

教训.p7b 签名描述文件是绑定 bundleName 的。跨项目复用签名材料,必报 SignHap 00303074每个项目都要重新自动签名。

坑 2:Hot Reload 模式导致 HAP 不完整

现象:HAP 装上了,但启动时报"主进程入口 main.js 找不到"。

在这里插入图片描述

原因:这是个很隐蔽的坑。DevEco Studio 默认跑的是 Hot Reload 模式,而这个模式只做增量编译——ArkTS 代码更新了,但 resfile 里的 Electron 资源(main.cjs、renderer 产物)没有被完整打进去

截图里那张状态表说得很清楚:

检查项 状态
build-profile.json5 ✅ modules 配置正确
app.json5 bundleName ✅ 与签名匹配
sync output.json ✅ BUNDLE_NAME 已修正
构建产物 ⚠️ HAP 使用 Hot Reload 模式,需要重新完整构建

解决办法:不要用 Hot Reload。在 DevEco Studio 的运行配置里,选 Application → electron,然后点运行,IDE 会自动完整重建并部署。

教训:Electron 类型的鸿蒙应用,资源文件通过 resfile 目录打包,Hot Reload 的增量机制覆盖不到。必须完整构建。

坑 3:resfile 资源缺失,Agent 自己补

现象:应用装上了,但 Electron 找不到主进程入口。

resfile 资源修复

Agent 的排查

# 检查 resfile 资源是否存在
ls web_engine/src/main/resources/resfile/resources/app/

发现 resfile 目录存在,但里面的资源不完整。于是它自己动手补齐:

  1. 创建主进程产物 main.cjs
  2. 复制 preload.cjs
  3. 复制 renderer 渲染产物(index.htmlmain-*.jspolyfills-*.jsstyles-*.cssassets/

这一步如果手工做,至少要 20 分钟还得小心翼翼。 Agent 几分钟搞定,还顺手验证了目录结构。

坑 4:katex 依赖缺失

现象:Angular 构建报 marked-katex-extension 相关错误。

katex 依赖修复

原因:Mockoon 的文档渲染用到了 KaTeX(数学公式渲染),但 katex 包没有在 monorepo 根显式声明。

Agent 的处理

npm install marked-katex-extension
npm install katex
npx ng build --configuration=development --base-href / 2>&1 | tail -30

装完重新构建,成功:

Angular build successful!

教训:monorepo 项目里,间接依赖经常没在根 package.json 声明。构建报错时先看是不是缺包,别急着重构代码。

四个坑的共同点

回头看这四个坑,我发现一个规律:没有一个是"算法问题"或者"架构问题",全都是"环境 / 配置 / 依赖"问题。

而这恰恰是 AI 最擅长的领域——它有足够的耐心去 grep、去 ls、去试错,而人早就烦了。


十二、成功启动:那个绿字等了四个半小时

回到 DevEco Studio,选中 Application → electron,点运行。

启动成功

底部日志,一行行看:

08/29, 12:14:31 AM: Launching com.example.pcmockoon
08/29, 12:14:34 AM: $ aa force-stop com.example.pcmockoon
08/29, 12:14:35 AM: $ bm install -p /storage/Users/currentUser/Documents/DevEcoStudioProjects/PCMockoon/build/default/outputs/default/electron-default-...
08/29, 12:14:36 AM: $ aa start -a EntryAbility -b com.example.pcmockoon in 308 ms
08/29, 12:14:36 AM: Launch com.example.pcmockoon success in 2 s 715 ms

Launch com.example.pcmockoon success in 2 s 715 ms

看到这行绿色字的时候,说实话,有点小激动。从晚上 8 点 04 分敲下第一句话,到凌晨 0 点 14 分跑起来,四个半小时。而这个过程中,我真正动手敲的代码,不超过十行。


十三、功能验收:不是能启动就行

能启动只是及格线。我开始挨个功能点验证。

13.1 主界面 + 路由列表

Mockoon 运行 - 主界面与路由

Mockoon 的主界面完整渲染出来了:

  • 左侧:环境导航(Demo API)、Routes / Data / Headers / Callbacks / Logs / Proxy / Settings 全部 tab 齐全
  • 中间:7 条路由规则(CRUD 全家桶:GET / POST / PUT / DELETE / PATCH 等)
  • 右侧:完整的响应配置面板

UI 渲染 100% 还原,没有样式错乱,字体、配色、间距全部正常。 这说明 Angular 22 的构建产物在鸿蒙 Web 组件里跑得很好。

13.2 数据桶:Mock 数据真的能生成

点开 Data tab:

Mockoon 数据桶

这一张是验证"真能用"的关键证据。

数据桶里的 50 条 mock 记录完整展示,每条都是 faker 生成的假数据(idusername 等字段)。这说明:

  1. 主进程的 Mock 引擎(Express + Handlebars)真的在跑
  2. 主进程 → 渲染进程的 IPC 通信是通的(数据从 Node 侧送到了 Angular 侧)
  3. 数据生成逻辑(faker)在鸿蒙上正常工作

不是"界面能显示"就叫适配成功,核心业务逻辑能跑通才算。

13.3 Headers:CORS 配置完整可用

Headers tab:

Mockoon Headers 配置

CORS 相关配置项一应俱全:

  • Content-Type
  • Access-Control-Allow-Origin
  • Access-Control-Allow-Methods
  • Access-Control-Allow-Headers
  • “Add CORS headers” 快捷按钮

13.4 Proxy:代理模式全选项在位

Proxy tab:

Mockoon Proxy 代理配置

  • Enable proxy mode 开关
  • Target URL 输入框
  • Remove Prefix 选项
  • Proxy request headers / Proxy response headers 配置区

四个 tab 挨个点过去,功能全部在位,没有一个是灰的、没有一个是报错的。

13.5 验收结论:什么叫"真的适配成功了"

看到这里,我想停下来聊聊一个标准问题——到底什么程度才算"适配成功"?

社区里经常看到有人说"我把某某软件搬到鸿蒙上了",点进去一看,要么只是个网页快捷方式,要么界面能打开但点什么都没反应。这不叫适配,这叫"能启动"。

我给自己定的验收标准有三条,这次 Mockoon 三条全部满足:

标准 具体要求 Mockoon 达成情况
界面完整 UI 渲染无错乱,样式、字体、交互全部正常 ✅ 100% 还原,Angular 产物完美渲染
主进程业务可用 核心业务逻辑(不只是界面)能跑通 ✅ Mock 引擎、faker 数据生成均正常
跨进程通信正常 主进程 ↔ 渲染进程 IPC 双向通畅 ✅ 数据桶内容通过 IPC 正确送达

第三条最容易被忽略,也最关键。 很多 Electron 应用移植后界面正常、但 IPC 断了,结果是"看着能用,点一下就废"。验证方法就是找一个必须走 IPC 才能拿到数据的功能去点——Mockoon 里就是数据桶,数据在主进程生成、通过 IPC 送到渲染进程显示。能看到 50 条 faker 数据,就证明整条链路是通的。


十四、原理篇:Electron 应用在鸿蒙上是怎么跑起来的

看完了操作流程,你可能还是有点懵:Electron 不是依赖 Chromium 和 Node.js 吗?鸿蒙 PC 上哪来的这两个东西?

这一节我就把这个道理讲透。理解了原理,你换任何一个 Electron 应用都知道该怎么下手。

14.1 核心思路:把 Electron 运行时"塞"进 HAP

答案藏在 HarmonyOS 社区的一个关键项目里——openharmony-sig/electron。社区把 Electron 的底层(Chromium + Node.js)编译成了鸿蒙平台可用的原生库,也就是 libelectron.so

于是适配思路就变成了:

在这里插入图片描述

一句话总结:鸿蒙侧提供"壳"和"运行时",你的 Electron 应用提供"内容"。两者在 resfile/resources/app/ 这个目录完成对接。

14.2 三个关键机制

机制 说明 适配时注意事项
resfile 资源打包 resfile 是鸿蒙的"原始资源目录",里面的文件会被原样打进 HAP,不编译、不压缩 所有 Electron 产物必须放这里,路径不能错
WebAbility 承载 EntryAbility 继承 WebAbility,由它在窗口里创建 Web 组件并拉起 Electron 这个文件通用,换应用不用改
libelectron 替换 electron npm 包不再提供运行时,改由 libelectron.so 提供 所以必须在打包时 external: ['electron']

14.3 为什么"零原生依赖"这么重要

这里要解释一下为什么我前面反复强调 Mockoon"零原生 addon"。

Electron 应用的依赖分两类:

依赖类型 举例 鸿蒙上的处理方式
纯 JS 依赖 express、lodash、handlebars、faker ✅ 直接打包进 main.cjs,无需处理
原生 addon better-sqlite3、node-gyp、keytar、sharp、canvas ❌ 需要 .node 二进制,必须为鸿蒙平台重新编译

如果一个应用依赖了原生 addon,你就得:

  1. 拿到该 addon 的 C/C++ 源码
  2. 用鸿蒙 NDK 交叉编译
  3. 处理各种平台相关的系统调用差异
  4. 祈祷它能跑起来

每一步都是数天的工作量,而且成功率不高。

Mockoon 的 Mock 服务核心用的是 Node.js 内置 http 模块 + Express,全是纯 JS,一个原生 addon 都没有。这就是为什么它能一次跑通。

所以选型第一原则:拿到一个 Electron 项目,先 grep 它的 package.json,看看有没有原生依赖。有的话,评估工作量要翻五倍。

# 快速判断一个项目能不能直接承载
grep -E '"(better-sqlite3|node-gyp|sqlite3|keytar|node-sass|sharp|canvas|usb|serialport|robotjs)"' \
  package.json */package.json

14.4 双模块 HAP 结构:为什么是 electron + web_engine

你可能注意到了,工程里有 electronweb_engine 两个模块。为什么要拆成两个?

模块 类型 职责 是否绑定应用
electron entry(宿主) 应用入口、Ability、原生库 半绑定(改名即可复用)
web_engine HAR(静态库) Electron 适配框架 + 应用资源 绑定(每个应用内容不同)

这样拆分的好处是:Electron 适配框架被沉淀成 HAR,换应用时只需要替换 web_engine 里的资源,宿主模块基本不用动。

这也是 CodeArts Agent 能直接复制 ohos_Zettlr 模板的原因——它识别出这两个模块是"通用底座",只需把里面的应用资源换成 Mockoon 的即可。

十五、技术拆解:核心代码逐行讲

光看热闹不够,下面把真正起作用的代码摆出来。这几段是本次适配的"命门",每一行都有讲究。

15.1 改动一:esbuild 打包策略(最核心)

文件mockoon-src/packages/app/src/main/esbuild.config.js

这是整个适配中最关键的一处改动,没有之一。

const path = require('path');
const esbuild = require('esbuild');

const args = process.argv.slice(2);
const modeIndex = args.indexOf('--mode');
const mode = modeIndex !== -1 ? args[modeIndex + 1] : 'production';
const isDev = mode === 'development';
const isTesting = args.includes('--testing');
const watch = args.includes('--watch');

const appRoot = path.resolve(__dirname, '../..');

const commonOptions = {
  bundle: true,
  platform: 'node',
  format: 'cjs',
  target: 'node24',
  outdir: path.resolve(__dirname, '../../dist'),
  sourcemap: isDev,
  minify: !isDev,
  // ↓↓↓ 核心改动在这里 ↓↓↓
  packages: 'bundle',        // 原来是 'external'
  external: ['electron'],    // 只把 electron 排除在外
  // ↑↑↑ 核心改动在这里 ↑↑↑
  alias: {
    src: path.resolve(appRoot, 'src')
  },
  define: {
    IS_DEV: isDev ? 'true' : 'false',
    IS_TESTING: isTesting ? 'true' : 'false',
    WEBSITE_URL: JSON.stringify(
      isDev ? 'http://localhost:3000/' : 'https://mockoon.com/'
    ),
    API_URL: JSON.stringify(
      isDev ? 'http://localhost:5003/' : 'https://api.mockoon.com/'
    )
  },
  logLevel: 'info'
};

async function run() {
  const options = {
    ...commonOptions,
    entryPoints: {
      app: path.resolve(appRoot, 'src/main/app.ts'),
      preload: path.resolve(appRoot, 'src/main/preload.ts')
    }
  };

  if (watch) {
    const context = await esbuild.context(options);
    await context.watch();
    return;
  }

  await esbuild.build(options);
}

run().catch((error) => {
  console.error(error);
  process.exit(1);
});

为什么必须改这两行?

配置 原值 新值 原因
packages 'external' 'bundle' 原来不打包 npm 依赖,运行时从 node_modules 加载。但鸿蒙 HAP 里根本没有 node_modules,必须把依赖全打进 app.js
external ['electron'] 只有 electron 要排除。因为鸿蒙上 Electron 由 libelectron.so 运行时提供,不能打包进去,否则会和运行时冲突

这一个改动的直接后果app.js 从几百 KB 膨胀到 6.1 MB——因为所有依赖都被打进去了。这是必然的代价,也是正确的代价。

15.2 改动二:preload 路径与图标路径

文件mockoon-src/packages/app/src/main/libs/main-window.ts

import { BrowserWindow, Menu, shell } from 'electron';
import windowState from 'electron-window-state';
import { join as pathJoin } from 'path';
import { argv } from 'process';
import { parseProtocolArgs } from 'src/main/libs/custom-protocol';
import { createMenu } from 'src/main/libs/menu';
import { getRuntimeArg } from 'src/main/libs/runtime-args';
import { checkForUpdate } from 'src/main/libs/update';

declare const IS_DEV: boolean;

let openUrlArgs: string[];
let mainWindow: BrowserWindow;

export const initMainWindow = () => {
  const enableDevTools = IS_DEV || !!getRuntimeArg('enable-dev-tools');

  const mainWindowState = windowState({
    defaultWidth: 1024,
    defaultHeight: 768
  });

  mainWindow = new BrowserWindow({
    x: mainWindowState.x,
    y: mainWindowState.y,
    minWidth: 1024,
    minHeight: 768,
    resizable: true,
    maximizable: true,
    minimizable: true,
    width: mainWindowState.width,
    height: mainWindowState.height,
    title: 'Mockoon',
    backgroundColor: '#252830',
    // ↓↓↓ 改动 1:图标路径指向 renderer/assets 下 ↓↓↓
    icon: pathJoin(
      __dirname,
      'renderer/assets/favicon-96x96.png'
    ),
    show: false,
    webPreferences: {
      nodeIntegration: false,
      contextIsolation: true,
      sandbox: true,
      devTools: enableDevTools,
      spellcheck: false,
      // ↓↓↓ 改动 2:preload.js → preload.cjs ↓↓↓
      preload: pathJoin(__dirname, '/preload.cjs')
    }
  });

  // maximize before showing the window to avoid a resize event on start
  if (mainWindowState.isMaximized) {
    mainWindow.maximize();
  }

  if (enableDevTools) {
    mainWindow.webContents.openDevTools();
  }

  // when main page finished loading, show the main window
  mainWindow.webContents.on('dom-ready', () => {
    showMainWindow(mainWindowState);
    checkForUpdate(mainWindow);
  });
};

两处改动的理由

改动 原因
preload.jspreload.cjs 打包到 HAP 后,package.json 没有声明 "type": "module".js 会被当作 ESM 处理导致加载失败。改成 .cjs 明确声明 CommonJS
icon → renderer/assets/favicon-96x96.png 原图标路径指向 node_modules 或构建期临时目录,HAP 里不存在。改为指向已部署的渲染产物目录

注意 webPreferences 里这几个安全配置,全都保留原样,一个都不能动

nodeIntegration: false,   // 渲染进程不集成 Node(安全)
contextIsolation: true,   // 上下文隔离(安全)
sandbox: true,            // 沙箱模式(安全)

这些是 Electron 的安全最佳实践。适配时千万不要为了"图省事"把它们关掉——关掉可能能跑,但会引入严重安全风险。

15.3 改动三:应用入口 package.json

文件ohos_hap/web_engine/src/main/resources/resfile/resources/app/package.json

{
  "name": "mockoon",
  "version": "9.8.0",
  "description": "Mockoon is the easiest and quickest way to run mock APIs locally. No remote deployment, no account required.",
  "main": "main.cjs",
  "author": {
    "name": "Mockoon",
    "url": "https://mockoon.com/"
  },
  "license": "MIT",
  "dependencies": {}
}

两个必须遵守的规则

规则 说明
"main": "main.cjs" 必须指向打包后的主进程产物,不能是 app.js 或其他
"dependencies": {} 必须是空对象! 绝对不能写 "dependencies": { "electron": "43.x" }。因为鸿蒙上 Electron 由运行时提供,声明了反而会让 Electron 尝试去 node_modules 找它,直接崩溃

15.4 关键文件:preload.cjs(安全桥接层)

这是主进程和渲染进程之间的"安全桥梁",用 contextBridge 暴露受控的 IPC 能力:

"use strict";

// 允许「渲染进程 → 主进程」单向发送的频道白名单
const SEND_CHANNELS = [
  "APP_APPLY_UPDATE", "APP_UPDATE_MENU_STATE", "APP_LOGS", "APP_QUIT",
  "APP_HIDE_WINDOW", "APP_UPDATE_ENVIRONMENTS", "APP_UPDATE_DISABLED_ROUTES",
  "APP_WRITE_CLIPBOARD", "APP_OPEN_FILE", "APP_SHOW_FILE", "APP_SHOW_FOLDER",
  "APP_ZOOM", "APP_AUTH", "APP_AUTH_STOP_SERVER"
];

// 允许「渲染进程 → 主进程」请求响应(invoke)的频道白名单
const INVOKE_CHANNELS = [
  "APP_GET_MIME_TYPE", "APP_GET_HASH", "APP_GET_FILENAME",
  "APP_BUILD_STORAGE_FILEPATH", "APP_GET_BASE_PATH",
  "APP_REPLACE_FILEPATH_EXTENSION",
  "APP_SERVER_GET_PROCESSED_DATABUCKET_VALUE", "APP_READ_CLIPBOARD",
  "APP_READ_FILE", "APP_READ_ENVIRONMENT_DATA", "APP_READ_SETTINGS_DATA",
  "APP_SHOW_OPEN_DIALOG", "APP_SHOW_SAVE_DIALOG", "APP_START_SERVER",
  "APP_STOP_SERVER", "APP_WRITE_FILE", "APP_WRITE_ENVIRONMENT_DATA",
  "APP_WRITE_SETTINGS_DATA", "APP_GET_OS", "APP_UNWATCH_FILE",
  "APP_UNWATCH_ALL_FILE"
];

// 允许「主进程 → 渲染进程」推送的频道白名单
const RECEIVE_CHANNELS = [
  "APP_MENU", "APP_SERVER_EVENT", "APP_UPDATE_AVAILABLE",
  "APP_AUTH_CALLBACK", "APP_CUSTOM_PROTOCOL", "APP_FILE_EXTERNAL_CHANGE"
];

const { contextBridge, ipcRenderer } = require("electron");

const api = {
  // 单向发送:只放行白名单频道
  send: (channel, ...args) => {
    if (SEND_CHANNELS.includes(channel)) {
      ipcRenderer.send(channel, ...args);
    }
  },
  // 请求响应:只放行白名单频道,其余直接 reject
  invoke: (channel, ...args) => {
    if (INVOKE_CHANNELS.includes(channel)) {
      return ipcRenderer.invoke(channel, ...args);
    }
    return Promise.reject("Invalid channel");
  },
  // 接收推送:只放行白名单频道
  receive: (channel, func) => {
    if (RECEIVE_CHANNELS.includes(channel)) {
      ipcRenderer.on(channel, (event, ...args) => func(...args));
    }
  }
};

// 通过 contextBridge 安全地暴露到渲染进程的 window.api
contextBridge.exposeInMainWorld("api", api);

这段代码的模式值得所有 Electron 适配者抄作业:三张白名单 + contextBridge,既保证了功能完整(39 个频道),又保证了安全(非白名单频道一律拒绝)。

15.5 鸿蒙宿主:EntryAbility.ets

文件ohos_hap/electron/src/main/ets/entryability/EntryAbility.ets

这个是鸿蒙侧的入口 Ability,继承自 WebAbility(来自 web_engine HAR):

// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import window from '@ohos.window';
import Want from '@ohos.app.ability.Want';
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
import { Configuration } from '@ohos.app.ability.Configuration';

import { WebAbility } from 'web_engine';

export default class EntryAbility extends WebAbility {
  onConfigurationUpdate(config: Configuration) {
    super.onConfigurationUpdate(config);
  }

  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
    super.onCreate(want, launchParam);
  }

  onDestroy() {
    super.onDestroy();
  }

  onWindowStageCreate(windowStage: window.WindowStage) {
    super.onWindowStageCreate(windowStage);
  }

  onWindowStageDestroy() {
    super.onWindowStageDestroy();
  }

  onForeground() {
    super.onForeground();
  }

  onBackground() {
    super.onBackground();
  }
};

注意这个文件是"通用不绑定 app"的——它不包含任何 Mockoon 的业务代码,所有生命周期都直接透传给 WebAbility。这样做的好处是:换一个 Electron 应用,这个文件一行都不用改。

十六、踩坑清单:一表速查

把全文的坑和项目里积累的坑汇总成一张表,建议收藏:

# 现象 对策
1 系统版本不够 CodeArts Agent 搜不到 / 打不开 系统升级到 6.1.0.135 以上
2 bundleName 不匹配 SignHap 00303074 每个项目重新自动签名;.p7b 绑定 bundleName
3 signingConfig 留空 输出 unsigned.hap,安装报 9568320 products[].signingConfig 必须填 signingConfigs 中的 name
4 Hot Reload 不完整 “main.js 找不到” Application → electron 完整构建,不用 Hot Reload
5 esbuild external 运行时找不到依赖模块 packages: 'external''bundle',仅 external: ['electron']
6 preload 扩展名 preload 加载失败 preload.jspreload.cjs
7 base href 绝对路径 资源 404,白屏 Angular 构建加 --base-href /,index.html 用 ./
8 package.json 声明 electron Electron 启动崩溃 dependencies 必须是 {}
9 Node.js 版本低 Angular CLI 报错 Node.js >= 22.12.0(推荐 22.22.3+)
10 间接依赖缺失 构建报模块找不到 手动 npm install katex 等缺失包
11 V8 JIT 兼容问题 构建 / 运行异常 设置 NODE_OPTIONS=--jitless
12 uv_cwd 错误 hvigor 守护进程 cwd 丢失 hvigorw --stop-daemonrm -rf .hvigor
13 GPU 加速问题 渲染异常 / 黑屏 app.disableHardwareAcceleration() + --disable-gpu,且必须最前置
14 resfile 资源缺失 主进程入口找不到 检查 web_engine/src/main/resources/resfile/resources/app/ 完整性
15 GitHub 克隆不通 git clone 超时 换镜像站或直接下载 zip

十七、CodeArts Agent 表现评估:客观说优缺点

用了8个半小时,我给它打个分。

17.1 干得漂亮的地方

能力 具体表现 评分
环境自适应 git 不通换镜像、unzip 不行换 Node 库,自主排除法探测 ⭐⭐⭐⭐⭐
联网查文档 主动查鸿蒙官方文档,不靠过期记忆瞎编 ⭐⭐⭐⭐⭐
复用先例 主动识别 ohos_Zettlr 模板并复制,省两天工作量 ⭐⭐⭐⭐⭐
改完自检 清理品牌残留后主动 grep 验证 ⭐⭐⭐⭐⭐
工程化输出 生成改动总表、README、构建脚本 ⭐⭐⭐⭐
命令执行 会检查退出码、会 tail 日志、会设置 NODE_OPTIONS ⭐⭐⭐⭐

17.2 还差点意思的地方

不足 说明
不能碰签名 涉及华为账号登录的操作必须人工做
偶尔绕远路 解压 zip 试了 4 种方案才成功,有一定时间浪费
长任务偶发中断 超长构建过程需要盯着,偶尔要补一句"继续"
不知道你的私有经验 必须主动 @ 喂文档,否则会走弯路

17.3 我的使用心得(三条)

第一条:先把地基打牢,再交给 Agent。

签名配好、Hello World 跑通、工程能编译——这三件事必须人工确认。Agent 干不了签名的活,地基不稳它再厉害也白搭。

第二条:把历史经验喂给它。

我这次能一次成功,docs/ 里那几份实战手册功不可没。Agent 会认真读,而且读得很仔细。你的经验库越厚,Agent 越强。

第三条:盯住它的命令,别完全放手。

Agent 会执行 shell 命令,虽然大多数时候是对的,但涉及删除、覆盖、全局安装的命令,最好看一眼再放行。人机组队,不是人交给机器。

在这里插入图片描述

十八、给后来者的适配路线图

如果你也想把一个 Electron 应用搬到鸿蒙 PC,按这个顺序来:
在这里插入图片描述

十九、常见问题 FAQ

把评论区最可能被问到的几个问题,先在这里答了。

Q1:我的鸿蒙 PC 系统版本是 6.1.0.125,能用 CodeArts Agent 吗?

不能,必须先升级到 6.1.0.135 及以上。

这是硬性门槛,不是建议。版本不够的情况下,应用市场里可能搜不到 CodeArts Agent,或者装上了也打不开。升级方法:设置 → 系统和更新 → 软件更新,检查更新即可。升级前记得保存好手头的文件。

Q2:DevEco Studio 和 CodeArts Agent 必须都装吗?只装一个行不行?

不行,两个都得装,它们干的是不同的活。

DevEco Studio 负责建工程、配签名、编译 HAP、部署到真机——这些涉及华为账号登录和官方工具链的操作,CodeArts Agent 干不了。CodeArts Agent 负责读源码、查文档、改代码、敲命令、排错——这些才是 AI 的主场。

它们通过同一个工程目录协同工作:Agent 改完代码,DevEco Studio 编译部署。缺任何一个,链路都不完整。

Q3:为什么一定要先跑通 Hello World 再交给 Agent?

因为 Hello World 跑通这一个动作,同时验证了四件事:

  1. 签名是对的(HAP 能装上真机)
  2. 真机连接是通的(能部署)
  3. 工具链是完整的(hvigor / ohpm 正常)
  4. SDK 版本配置是匹配的

这四件事任何一件不通,Agent 改再多代码都白搭——编译都过不了,改什么都没意义。而且签名这事儿 Agent 干不了,必须你先配好。地基不打牢,AI 也救不了。

Q4:我没有已适配成功的先例工程,能直接用 CodeArts Agent 吗?

能,但工作量会大很多。

我这次能四个半小时搞定,一个关键原因是工作区里已经有 ohos_Zettlr 这个成功案例,Agent 直接复制了它的双模块 HAP 骨架和 libelectron.so,省了至少两天。

如果没有先例,你得让 Agent 从 HarmonyOS SIG 的 electron 仓库拉基础模板,再自己搭结构。建议的做法是:先去社区找一找同类型(Electron / Web 类)已适配的项目,fork 一份作为起点。

社区地址:https://atomgit.com/OpenHarmonyPCDeveloper

Q5:改 esbuild 配置时,packages: 'bundle' 会让产物变大很多,有影响吗?

有影响,但这个影响是必须接受的

原本 packages: 'external' 模式下,npm 依赖不会被打包,运行时从 node_modules 目录加载。但鸿蒙 HAP 里根本没有 node_modules,所以不打包就找不到依赖,应用直接崩。

改成 bundle 后,所有依赖被打进 app.js,体积从几百 KB 涨到 6.1 MB。代价是包更大、启动稍慢,收益是能跑起来。两害相权取其轻。

Q6:Hot Reload 这么方便,为什么不能用?

因为 Hot Reload 的增量编译覆盖不到 resfile 资源目录

鸿蒙的 Hot Reload 主要针对 ArkTS 代码做增量更新,而 Electron 应用的核心产物(main.cjs、renderer 下的 JS / CSS / HTML)都躺在 resfile 里。用 Hot Reload 模式跑,ArkTS 更新了但 Electron 资源没更新,结果就是启动时报"主进程入口找不到"。

正确做法:运行配置里选 Application → electron,让 IDE 做完整构建。虽然慢一点,但产物是完整的。

Q7:适配完之后,上游 Mockoon 出新版本了怎么办?

这正是"只改 3 个上游文件"的价值所在。

改动越少,合并上游更新时的冲突就越少。我的做法是:

  1. 拉取上游新版本 tag
  2. 重新应用这 3 处改动(esbuild 配置、preload 路径、base href)
  3. 重新构建部署

因为改动都是"一行级别"的,即使上游有变化,手动合入也就几分钟的事。如果当初图省事做了大量侵入式修改,后续同步就会变成噩梦。

Q8:CodeArts Agent 改的代码靠谱吗?需要全部 review 吗?

核心改动必须 review,重复劳动可以放心交给它。

我的经验是:

  • 必须人工看:涉及路径、配置、依赖的改动(这类改动错了会直接崩,而且 Agent 不一定能自检出来)
  • 可以放心:批量替换、文件复制、文档生成这类机械劳动

好消息是 Agent 有自检习惯(比如清理品牌残留后会主动 grep 验证),但涉及删除、覆盖、全局安装的命令,我还是建议你看一眼再放行

Q9:这个方案能适配所有 Electron 应用吗?

不能,只适用于"零原生 addon 依赖"的纯 JS Electron 应用。

判断方法见 14.3 节。如果应用依赖了 better-sqlite3keytarsharpcanvas 这类需要编译的原生模块,就必须先解决原生模块的交叉编译问题,工作量会翻好几倍。

Q10:我想参与鸿蒙 PC 生态适配,从哪里开始?

三个入口:

  1. 社区:https://harmonypc.csdn.net/ —— 了解动态、找组织
  2. 项目申请:https://atomgit.com/OpenHarmonyPCDeveloper —— 申请新建适配项目
  3. 代码托管:AtomGit —— fork 先例工程,改起来

建议从 Web 类 / Electron 类应用入手,这类适配成功率最高、见效最快,容易建立信心。


二十、写在最后:鸿蒙 PC 的开发者生态正在成型

8个半小时,32 张截图,3 个上游文件改动,一个 Electron 43 + Angular 22 的大型开源项目,跑在了鸿蒙 PC 上。

回过头看,这次实践给我最大的感受不是"AI 很强"——AI 强是大家都知道的事。真正让我意外的是:鸿蒙 PC 的这套工具链已经足够成熟了。

  • DevEco Studio 的自动签名,几步点完事
  • CodeArts Agent 能联网、能执行命令、能读工程上下文
  • HarmonyOS 定制的 Electron 运行时(libelectron.so)能直接承载成熟的 Electron 应用
  • 真机调试链路完整,日志清晰,错误码有据可查

这意味着"适配"的门槛正在快速下降。 以前要一个熟悉鸿蒙的工程师干一周的活,现在一个懂 Electron 的开发者 + CodeArts Agent,一个下午就能出结果。

Mockoon 只是开始。Zettlr、StandardNotes、JupyterLab、Flameshot、Terminator…… 这些桌面端常用工具,我们都在陆续往鸿蒙 PC 上搬。每适配一个,鸿蒙 PC 的开发者工具箱就丰富一分。

附录:参考链接

Logo

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