Electron 能跑在鸿蒙上?拆解这套把 Node 22 + Chromium 塞进 HAP 的运行时
Electron 能跑在鸿蒙上?你多半会以为是什么套壳方案。
不是。 harmonypc-electron 是真把 Node 22 + Chromium 搬进了 HAP——原生 SO 躺在 libs/arm64-v8a/ 里,ArkTS 桥接层负责把鸿蒙的系统能力暴露给 Node。
上篇我说「把 dsh 搬上鸿蒙,只换运行时」,这篇就把这个运行时拆开给你看:它由哪几块组成、Node 和鸿蒙怎么对上话、渲染面怎么贴,以及我们工程是怎么适配它的。看完你也能搞清楚「Electron-on-鸿蒙」到底是怎么一回事。
一、鸿蒙没有官方 Electron:三件事都得自己搭
鸿蒙的桌面形态(2in1 / 平板)没有官方 Electron。想在鸿蒙上跑一个依赖 Node 生态的桌面应用,有三件事得自己搭:
- 原生 SO:Electron 的二进制(Node + Chromium 引擎)
- 桥接层:让 Node 侧能调用鸿蒙的系统能力(窗口 / 通知 / 剪贴板 / 权限)
- 渲染面:把网页内容贴进鸿蒙窗口
harmonypc-electron 就是干这三件事的运行时。下面逐个拆。
二、拆成两个模块:一个管「跑」,一个管「接」
harmonypc-electron 拆成两个模块:
- electron(
type: entry,HAP 入口):承载原生 SO——libelectron.so(约 172MB)、libffmpeg.so、libadapter.so,外加libc++_shared.so。EntryAbility 从这里启动 Electron 运行时。 - web_engine(HAR 桥接层):ArkUI Web 组件 + 大量
*AdapterBind.ets(窗口 / 通知 / 剪贴板 / 权限…)+ jsbindings。你的 Electron 应用代码就放在它的resfile/resources/app/里。
一句话:electron 模块管「跑起来」,web_engine 模块管「接上鸿蒙」。
三、桥接三件套:aki / adapter / addon
最核心的是 Node ↔ ArkTS 的桥接,靠「三件套」:
| 组件 | 产物 | 作用 |
|---|---|---|
| aki | libaki_jsbind.so | JS 绑定框架(Node ↔ ArkTS 类型桥) |
| adapter | libadaptertest.so | 注册原生方法(getNativeContext + bindFunction) |
| addon | electron-addon.node(链 libshim.a) | Node 侧 require() 入口 |
数据流是这样:Node 侧 require('electron-addon.node') 拿到入口 → 通过 aki 的类型桥 → 调用 ArkTS 侧 JsBindingMethod.bind() 注册的方法。反过来,鸿蒙的系统事件也能经这条桥回传给 Node。
对我们这个工程来说,这套桥接大部分已经由运行时编译好了,我做的事只是接线——比如通知,订阅 dsh 的 ctx 事件后,经桥接触发鸿蒙通知即可。
四、渲染面:XComponent 贴的原生 Chromium,不是 ArkWeb
渲染层面,web_engine 用 XComponent(SURFACE) 承载一个原生 Chromium 渲染面,把 dsh Web UI 贴进鸿蒙窗口。
注意这个词——「原生 Chromium」,不是 ArkWeb。这点很关键,它直接埋下了后面「上架合规」的坑:AppGallery 要求「渲染网页必须用 ArkWeb」,而我们用的是随包 Chromium。这个坑我在「App 上架合规踩坑」篇会单独讲(还做了个 ArkWeb 的 PoC,结论是可行)。
五、为什么非 Electron 37 / Node 22.17.0 不可
运行时版本不是随便选的。dsh 依赖 node:zlib.createZstdDecompress(解压会话产物),这要求 Node 22+。
而 Electron 34 只带 Node 20.18.1,没有这个 API;Electron 37 的 Node 22.17.0 才行。SQLite 也顺带换了 better-sqlite3 的 Electron 37 / Node ABI v138 aarch64 成品。
六、适配纪律:copy + prune + overlay + bundleName 改写
本工程怎么「适配」这个运行时?核心是 collect-runtime.mjs 这一条流水线。纪律只有一句:「整目录 copy 会回滚你的定制」,所以必须靠下面几步保护:
- copy:把
../harmonypc-electron的 electron + web_engine 模块 + 3 个 SO 物理 copy 进本工程(sibling 存放、产物内嵌)。 - prune:删掉本应用不用的 4 个上游蓝牙文件(删前先断言存在,缺了硬失败——防止上游结构漂移被静默跳过)。
- overlay:把
runtime-overlays/里的定制文件回盖上去(module.json5、string.json、shortcuts 配置…)。 - bundleName 改写:把上游写死的包名字面量替换成应用自己的包名。
- 守卫:md5 一致性 + prune 文件必须不存在 + overlay 源仍含通用字面量,防止某一步静默回滚。
这套「copy 后必须重新施加定制」的纪律,是鸿蒙工程里最容易踩的坑之一——你改了个文件,一跑 collect-runtime,改动没了。
七、写在最后
以上就是 Electron-on-鸿蒙运行时的完整拆解:electron 模块跑起来 + web_engine 模块接鸿蒙 + aki/adapter/addon 三件套桥接 + XComponent 渲染面,适配靠 copy / prune / overlay / 改写 + 守卫。
如果你也在做 Electron 应用的鸿蒙化,这篇的运行时机理和适配纪律可以直接抄。
代码已开源:https://github.com/fellow99/dsh-desktop-hos ,欢迎 star 支持。
相关开源工程:
- DeepSeek Harness(上游项目):https://github.com/deepseek-ai/deepseek-harness
- dsh-market(插件市场):https://github.com/dsh-market/dsh-market
- harmonypc-electron(Electron-on-鸿蒙运行时):https://atomgit.com/jianguoxu/harmonypc-electron
- deepseek-harness-workspace(工作区总览):https://github.com/fellow99/deepseek-harness-workspace
- dsh-desktop(桌面端):https://github.com/fellow99/dsh-desktop
- dsh-desktop-hos(鸿蒙端):https://github.com/fellow99/dsh-desktop-hos
下一篇我写**「鸿蒙真机调试三板斧」**:主进程 inspector + CDP 自动化,还有为什么 Playwright 驱动不了它。关注我,别错过。
感谢各位关注,欢迎访问我的GitHub主页:https://fellow99.github.io/
更多推荐




所有评论(0)