← [ BACK_TO_NOTES ]

MemoFlow · Electron Desktop 开发笔记

按版本记录 Nx Monorepo、Electron IPC、本地持久化与独立 Profile 的架构设计。

#blog #growing #dev

Desktop 模块目标

我想在 DailyUse 的 Nx Monorepo 中实现 Electron Desktop,实践一种以多个业务 Package 拼装应用的方式。Desktop 不再是重新写一套业务代码的独立项目,而是提供窗口、文件系统、本地数据库和 IPC 等宿主能力的容器。

V1.0.0

先确定一个原则:业务能力放在可复用的 Package,Electron 主要负责把这些能力装配起来。

以创建 Goal 为例,流程是:

  1. Vue 页面打开创建表单并做输入校验。
  2. 客户端 Application 组织创建请求,通过基础设施层调用 IPC。
  3. Electron 主进程接收请求,再调用服务端 Application。
  4. 服务端应用服务使用 Goal 领域规则和 Repository 完成校验与持久化。
  5. 结果沿 IPC 返回,客户端更新界面。

这与把数据库操作直接写在 Vue 组件里不同。Presentation 只关注交互,Application 管用例,Domain 管业务规则,Infrastructure 负责连接 IPC、数据库等技术细节。

v1.1.0

Desktop 需要在离线时也能工作,因此本地持久化先选择 SQLite + better-sqlite3。

SQLite 不需要单独部署服务器,适合桌面端的本地事务;better-sqlite3 则提供 Node/Electron 主进程中的数据库访问能力。数据库连接与各模块的 Schema 由主进程统一装配,渲染层不能直接写 SQL。

同时要注意 Electron 的两个环境不是一回事:渲染进程运行网页 UI,主进程拥有 Node/OS 能力。跨过这条边界的请求需要明确的 IPC Contract、校验和错误传递。不能因为“都在一台电脑上”,就把文件系统和数据库权限全部暴露给渲染层。

V2.0.0

现在准备让 Web 和 Desktop 复用更多业务代码。目标不是让两端都使用 Electron IPC,而是让它们共享领域模型、用例和输入输出契约,再在宿主层选择不同 Adapter。

例如同一项业务在 Desktop 走 IPC 与本地 Repository,在 Web 走 HTTP 与服务端 Repository;客户端业务组件尽量不需要知道底下是哪一种 Transport。

这样能够减少同一个 Goal、Task 规则在两端出现两套实现。但抽象也不能过度:主进程文件访问、系统通知、窗口管理等就是 Desktop 专有能力,不需要伪造一个在 Web 里永远不可用的同等实现。

v2.1.0

多个账号开始使用 Desktop 后,光有“当前登录用户”还不够。需要设计稳定的 Local Profile,让不同用户的数据库、Vault、配置和运行态互相隔离。

Guest 也应该能在自己的 Profile 中离线使用业务;登录云端时,只建立明确的关联,不自动替换原本的本地容器。主进程负责 Profile 路径与数据库装配,渲染层按当前 Profile 读取业务,不能在账号切换后继续沿用上一个用户的状态。

v2.2.0

当 Desktop 要打包发布时,还得专门处理运行环境与开发环境的区别。

开发时能工作的依赖,在 Electron 打包后未必有相同的文件路径和加载方式。尤其是 better-sqlite3 这样的原生模块,需要关注 Electron ABI、构建产物位置以及 ESM/CommonJS 边界。

因此主进程启动、数据库初始化、用户数据路径、更新和打包后的基础业务流程都需要单独验证。Desktop 是宿主容器,但绝不是一个只负责打开网页的空壳。

创建于 2026/1/11 更新于 2026/10/17
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本