鸿蒙PC迁移:使用Electron`logseq-master-ohos` 鸿蒙适配全记录

文章目录

    • 一、写在前面
    • 二、项目背景
    • 三、总体变化概览
      • [3.1 新增鸿蒙工程壳](#3.1 新增鸿蒙工程壳)
      • [3.2 新增构建脚本](#3.2 新增构建脚本)
      • [3.3 新增运行时识别](#3.3 新增运行时识别)
      • [3.4 新增本地服务启动入口](#3.4 新增本地服务启动入口)
    • [四、为什么 Logseq 选择 Web release 优先](#四、为什么 Logseq 选择 Web release 优先)
    • 五、鸿蒙适配核心路径
      • [5.1 第一步:构建 Logseq Web release 产物](#5.1 第一步:构建 Logseq Web release 产物)
      • [5.2 第二步:同步资源到 HAP](#5.2 第二步:同步资源到 HAP)
      • [5.3 第三步:注入 OpenHarmony 运行标记](#5.3 第三步:注入 OpenHarmony 运行标记)
      • [5.4 第四步:生成本地服务入口](#5.4 第四步:生成本地服务入口)
      • [5.5 第五步:补齐 WebAssembly 启动参数](#5.5 第五步:补齐 WebAssembly 启动参数)
      • [5.6 第六步:给 SQLite 持久化增加 OpenHarmony 分支](#5.6 第六步:给 SQLite 持久化增加 OpenHarmony 分支)
      • [5.7 第七步:把图谱创建过程拆成可诊断阶段](#5.7 第七步:把图谱创建过程拆成可诊断阶段)
    • 六、问题困难解决
      • [6.1 困难一:鸿蒙日志噪声容易误导判断](#6.1 困难一:鸿蒙日志噪声容易误导判断)
      • [6.2 困难二:`null.oo1` 背后是 SQLite WASM 没起来](#6.2 困难二:null.oo1 背后是 SQLite WASM 没起来)
      • [6.3 困难三:传统 Electron 判断会把 Logseq 带到错误路径](#6.3 困难三:传统 Electron 判断会把 Logseq 带到错误路径)
      • [6.4 困难四:OPFS 不能当作唯一持久化基础](#6.4 困难四:OPFS 不能当作唯一持久化基础)
      • [6.5 困难五:窗口按钮不能只在页面里画出来](#6.5 困难五:窗口按钮不能只在页面里画出来)
      • [6.6 运行链路确认顺序](#6.6 运行链路确认顺序)
    • 七、构建与运行方式
    • 八、适配成果
    • 九、功能验证结果
    • 十、结语

一、写在前面

欢迎加入鸿蒙PC开发者社区,共同打造开发者工具生态:鸿蒙PC开发者社区 :https://harmonypc.csdn.net/

开源项目地址:https://atomgit.com/OpenHarmonyPCDeveloper/ohos_logseq

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

环境搭建文章:https://blog.csdn.net/lbcyllqj/article/details/161286249?sharetype=blogdetail\&sharerId=161286249\&sharerefer=PC\&sharesource=lbcyllqj\&spm=1011.2480.3001.8118

这篇文章记录的是 Logseq 在 OpenHarmony / HarmonyOS Electron 环境中的一次适配过程。

Logseq 是一个本地优先的知识管理和协作工具。它表面上是笔记软件,实际运行时会牵涉块编辑器、图谱、页面索引、搜索、SQLite、Web Worker、IndexedDB、OPFS、PDF、白板等一整套前端与本地数据能力。和普通 Web 工具不同,Logseq 不是页面打开就算迁移完成,它真正的关键在于:

图谱能不能创建,SQLite 能不能初始化,数据能不能落盘,重新打开以后还能不能回到同一个图谱。

针对鸿蒙适配,这次没有直接把桌面 Electron 版本完整搬过来,也没有用 ArkTS 重写业务界面,而是先选择一条更可控的路线:

使用 Logseq Web release 产物作为核心承载,由 OpenHarmony Electron runtime 启动本地服务并加载页面。

这样做的目标很明确:优先打通 Logseq 在鸿蒙窗口中的主界面、日记页、图谱创建、基础编辑、搜索弹层和本地持久化能力。等这条核心链路稳定以后,再继续考虑桌面端更重的文件系统、插件、同步、附件、PDF 标注等能力。

本文会按工程结构、资源同步、运行入口、数据库链路、问题定位和功能验证几个角度复盘这次适配。

先说结论:这次适配已经让 Logseq 在鸿蒙 Electron runtime 中完成了从 HAP 工程、Web 资源、运行入口、SQLite WASM 到图谱恢复的基础闭环。它不是一个只展示页面的壳,而是可以进入日记、打开搜索、进入编辑状态并保留图谱数据的知识库应用。


二、项目背景

Logseq 项目本身不是单一形态应用,它同时包含 Web、桌面端和移动端路径。

仓库中比较关键的目录和能力包括:

  • src/main/frontend/:Logseq 主前端逻辑,包含页面、编辑器、图谱、repo handler 等核心代码
  • src/main/frontend/worker/:浏览器侧 DB worker 与 SQLite WASM 相关逻辑
  • static/:Logseq Web release 构建后的静态资源目录
  • electron/src/electron/:传统桌面 Electron 相关能力
  • scripts/:构建、打包和本次新增的鸿蒙同步脚本
  • ohos_hap/:本次新增的鸿蒙 HAP 工程

Logseq 的运行路径可以粗略分成三类:

  1. 浏览器路径:ClojureScript、React/Rum、Web Worker、IndexedDB、OPFS、SQLite WASM
  2. 桌面路径:Electron 主进程、IPC、Node DB worker、better-sqlite3、本地文件系统
  3. 移动路径:Capacitor、移动端入口和原生插件

这次适配选择 Web release 作为鸿蒙第一阶段承载目标,主要原因是桌面端依赖更重。传统桌面版会涉及 better-sqlite3、文件系统 IPC、keychain、系统托盘、窗口菜单、全局快捷键、自动更新等能力。如果一开始就完整迁移桌面端,问题会迅速扩散到原生模块和系统 API 上。

Web release 路线能先把核心知识库体验收敛到浏览器能力上:页面渲染、worker、SQLite WASM、IndexedDB、图谱列表和基础持久化。对第一阶段来说,这条路更容易形成可验证结果。


三、总体变化概览

3.1 新增鸿蒙工程壳

适配后的项目新增:

text 复制代码
ohos_hap/
├── AppScope/
├── electron/
├── web_engine/
└── build-profile.json5

鸿蒙 Electron runtime 最终读取的应用资源目录是:

text 复制代码
ohos_hap/web_engine/src/main/resources/resfile/resources/app

同步后的资源目录大致是:

text 复制代码
resources/app/
├── main.js
├── package.json
└── www/
    ├── index.html
    ├── css/
    ├── js/
    └── ...

其中 www/ 是 Logseq Web release 产物,main.js 是为鸿蒙环境生成的 Electron 启动入口。

3.2 新增构建脚本

新增脚本:

text 复制代码
scripts/build-ohos-package.cjs
scripts/build-ohos-hap.cjs

package.json 中新增:

json 复制代码
{
  "ohos:sync": "node scripts/build-ohos-package.cjs",
  "ohos:build": "node scripts/build-ohos-hap.cjs"
}

这两条命令分别负责:

  • 构建或复用 Logseq Web release 产物
  • 将资源同步到 HAP 的 resources/app
  • 注入 OpenHarmony 运行标记
  • 生成轻量 Electron runtime 入口
  • 调用 Hvigor 构建 HAP

3.3 新增运行时识别

构建脚本会在 index.html 中注入:

js 复制代码
window.__LOGSEQ_OPENHARMONY__ = true;
window.__LOGSEQ_OPENHARMONY_BROWSER_STORAGE__ = true;

前端代码据此把 OpenHarmony Electron runtime 和传统桌面 Electron 区分开,避免 Logseq 误走 Node IPC、桌面 DB worker 和 better-sqlite3 路径。

3.4 新增本地服务启动入口

生成的 resources/app/main.js 不直接 loadFile(index.html),而是启动本地静态服务:

text 复制代码
http://127.0.0.1:37910/

再由 Electron 窗口加载这个地址。这样可以统一处理 MIME、资源回退、worker、WASM 以及跨源隔离相关响应头。


四、为什么 Logseq 选择 Web release 优先

Logseq 桌面版能力很完整,但对鸿蒙第一阶段来说,直接迁移桌面端不是最稳的起点。

桌面 Electron 路径里有几类问题会同时出现:

  • Node 原生模块需要重新适配或替代
  • better-sqlite3 依赖原生编译能力
  • 文件系统访问和图谱目录选择需要鸿蒙侧重新设计
  • 托盘、菜单、自动更新、全局快捷键等桌面能力不一定有同等 API
  • renderer 很容易误以为自己处在传统 Electron 环境,从而走错数据库链路

而 Web release 路径能先覆盖 Logseq 最核心的使用链路:

  • 页面加载
  • 日记页渲染
  • 图谱创建
  • DB worker 启动
  • SQLite WASM 初始化
  • IndexedDB 持久化
  • 搜索弹层
  • 块编辑入口

所以这次路线可以概括为:

static/ Web release 资源 + 本地 HTTP 服务 + OpenHarmony Electron 窗口 + HAP 工程承载。

这里和一些纯静态 Web 项目略有不同。Logseq 没有直接从 file:// 加载页面,而是通过本地服务加载 http://127.0.0.1:37910/。这样做是为了让 SQLite WASM、worker、SharedArrayBuffer 和资源类型处理更接近普通 Web 运行环境。


五、鸿蒙适配核心路径

5.1 第一步:构建 Logseq Web release 产物

scripts/build-ohos-package.cjs 会检查 static/ 下是否已经存在关键文件:

text 复制代码
static/index.html
static/js/main.js
static/js/db-worker.js
static/js/db-worker-bundle.js
static/js/sqlite3.wasm

如果缺少这些产物,脚本会执行 Logseq 的前端构建链路,包括:

text 复制代码
pnpm gulp:build
clojure -M:cljs release app db-worker db-worker-node
pnpm webpack-app-build

构建时会设置:

text 复制代码
LOGSEQ_OPENHARMONY_BUILD=1

并把 ClojureScript 的 asset-path 调整为本地 /js,避免 HAP 内运行时继续请求远端资源。

5.2 第二步:同步资源到 HAP

脚本会把 static/ 复制到:

text 复制代码
ohos_hap/web_engine/src/main/resources/resfile/resources/app/www

复制时会过滤 .DS_Store.cache 和 sourcemap,减少 HAP 内不必要的资源。

5.3 第三步:注入 OpenHarmony 运行标记

同步后会修改 www/index.html,写入:

js 复制代码
window.__LOGSEQ_OPENHARMONY__ = true;
window.__LOGSEQ_OPENHARMONY_BROWSER_STORAGE__ = true;

对应的前端判断是:

clojure 复制代码
(defn openharmony?
  []
  (boolean (and js/window
                (gobj/get js/window "__LOGSEQ_OPENHARMONY__"))))

(defn- electron*?
  []
  (when (and js/window
             (not (openharmony?))
             (gobj/get js/window "navigator"))
    (gstring/caseInsensitiveContains js/navigator.userAgent " electron")))

这一步很关键。OpenHarmony 里虽然使用 Electron runtime,但 Logseq 不能把自己当成传统桌面 Electron,否则会去找当前阶段并不存在的桌面 DB worker 和 Node IPC 能力。

5.4 第四步:生成本地服务入口

resources/app/main.js 会启动本地服务,默认端口:

text 复制代码
37910

服务会为资源设置:

text 复制代码
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Resource-Policy: same-origin

同时补充 .wasm.js.css、字体、图片等 MIME 类型。这样 SQLite WASM、worker 和前端资源都能在更稳定的 Web 运行模型下加载。

5.5 第五步:补齐 WebAssembly 启动参数

Logseq 的 SQLite 依赖 @sqlite.org/sqlite-wasm。鸿蒙 Electron runtime 里不能默认假设 WebAssembly 已经暴露出来,因此需要在两处补运行参数。

第一处是鸿蒙侧默认命令行参数:

ts 复制代码
"--js-flags=--expose-wasm",
"--enable-webassembly",
"--enable-features=UseOzonePlatform,SharedArrayBuffer,WebAssembly",

第二处是生成的 Electron 入口:

js 复制代码
app.commandLine.appendSwitch('js-flags', '--expose-wasm');
app.commandLine.appendSwitch('enable-webassembly');
app.commandLine.appendSwitch('enable-experimental-web-platform-features');
app.commandLine.appendSwitch('enable-features', 'SharedArrayBuffer,WebAssembly');

只改其中一处不够稳。鸿蒙 Electron 壳默认参数和应用包内生成入口都要覆盖,否则容易出现本次手动调通、下次重新打包又退回空白或数据库失败的情况。

5.6 第六步:给 SQLite 持久化增加 OpenHarmony 分支

Logseq 浏览器侧原本会优先尝试 OPFS 和 SQLite WASM 的 VFS 能力。OpenHarmony Electron runtime 对 OPFS、SAH pool、SharedArrayBuffer 这一组能力不能完全按桌面 Chromium 来假设。

因此 DB worker 增加了 OpenHarmony 分支:

  • worker URL 带上 openharmony=true
  • OpenHarmony 下跳过 OPFS SAH pool
  • 图谱列表保存到 IndexedDB
  • SQLite DB 内容导出成二进制 payload 后保存到 IndexedDB
  • 下次打开图谱时从 IndexedDB 还原数据库文件

使用的 key 包括:

text 复制代码
logseq-openharmony-graphs/v1
logseq-openharmony-db/v1/<encoded>

这里还有一个细节:没有有效 payload 时不创建 0 字节 SQLite 文件。0 字节文件会让后续打开数据库时变得更难判断,看起来像"文件存在但数据库损坏"。适配里只在 IndexedDB 里确实存在正长度数据时才恢复。

5.7 第七步:把图谱创建过程拆成可诊断阶段

Logseq 启动空白或点击无反应时,只看鸿蒙设备日志很容易被干扰。比如剪贴板、输入法、GPU、DNS、窗口事件都可能输出 error 或 warning,但不一定是根因。

这次在图谱创建链路里增加了 stage 诊断:

text 复制代码
persist-new
start-conn
add-repo
restore-setup
redirect-home
repo-config

如果失败,页面会提示:

text 复制代码
创建图谱失败。 stage=<stage> error=<message>

同时会记录当前环境中 WebAssemblyWorkerSharedArrayBuffer 等能力是否存在。这样就能把"空白页""点击没反应"拆成具体阶段,定位效率会高很多。


六、问题困难解决

Logseq 适配中最大的困难是:

页面加载成功以后,图谱创建链路仍然可能失败,而失败表象经常只是空白或点击无反应。

这个问题主要集中在四个方面。

6.1 困难一:鸿蒙日志噪声容易误导判断

启动时可以看到一些比较醒目的日志,例如:

text 复制代码
XComponentManager::Initialize napi_unwrap fail
PermissionManagerAdapter unsupported permission:pasteboard
clipboard_ohos.cc load OH_Pasteboard_GetChangeCount failed

这些日志说明鸿蒙 Electron 适配层里仍有一些能力差异,但它们不是 Logseq 空白或无法创建图谱的根因。

真正需要盯的是 Logseq 自己的图谱创建链路、DB worker 初始化和 SQLite WASM 加载结果。迁移时不能看到 error 就马上改方向,需要把系统适配层噪声和应用自身错误分开。

6.2 困难二:null.oo1 背后是 SQLite WASM 没起来

早期失败时出现过:

text 复制代码
Cannot read properties of null (reading 'oo1')

这个错误表面像是普通空对象访问,实际是 SQLite WASM 模块没有初始化成功。后续代码继续访问 sqlite.oo1.DB,于是变成了 null.oo1

所以适配里做了两件事:

  1. SQLite 初始化完成后检查 oo1.DBcapi 是否存在
  2. 图谱创建失败时把 stage 和真实错误显示出来

处理后错误可以收敛成:

text 复制代码
创建图谱失败。 stage=persist-new error=WebAssembly is not defined

这个提示出现以后,方向就非常明确了:不是图谱 UI 坏了,也不是路由坏了,而是运行环境里的 WebAssembly 没有打开。

6.3 困难三:传统 Electron 判断会把 Logseq 带到错误路径

鸿蒙里使用 Electron runtime,但这不等于 Logseq 可以直接走传统桌面 Electron 分支。

传统桌面分支会依赖:

  • Electron IPC
  • Node DB worker
  • better-sqlite3
  • 本地文件系统图谱目录
  • 桌面端窗口和系统能力

这些能力在第一阶段并不是迁移目标。适配中通过 __LOGSEQ_OPENHARMONY__ 把 OpenHarmony 单独识别出来,让 Logseq 继续沿浏览器侧 DB worker 和 SQLite WASM 路径运行。

这个判断看起来只是一小段环境识别代码,但它决定了后续数据库链路走向。

6.4 困难四:OPFS 不能当作唯一持久化基础

普通 Chromium 环境中,OPFS 与 SQLite WASM 可以形成比较理想的浏览器侧数据库方案。但在 OpenHarmony Electron runtime 中,这组能力的行为需要重新验证。

所以适配里增加 IndexedDB 兜底持久化:

  • 图谱列表存 IndexedDB
  • SQLite DB blob 存 IndexedDB
  • 重启时再恢复到 SQLite 文件

这不是为了替代 Logseq 后续更完整的文件系统能力,而是为了第一阶段先保证"创建图谱 -> 进入日记 -> 重启恢复"这条链路不会断。

6.5 困难五:窗口按钮不能只在页面里画出来

用户实际使用时会关注鸿蒙外壳有没有最小化、最大化、关闭按钮。这个问题不能通过在 Logseq 页面里画三个按钮解决,因为它属于窗口装饰和 runtime 行为。

生成的 BrowserWindow 中设置了:

js 复制代码
frame: true,
titleBarStyle: 'default',
minimizable: true,
maximizable: true,
closable: true,
resizable: true

这样窗口控制权交给鸿蒙 Electron runtime,应用界面本身只负责 Logseq 内容。

6.6 运行链路确认顺序

Logseq 在鸿蒙中的运行链路可以按下面顺序确认:

  1. static/index.htmlstatic/js/main.jsstatic/js/db-worker.jsstatic/js/sqlite3.wasm 是否生成
  2. resources/app/www 是否同步成功
  3. resources/app/package.jsonmain 是否指向 main.js
  4. 本地服务是否加载 http://127.0.0.1:37910/
  5. window.__LOGSEQ_OPENHARMONY__ 是否注入
  6. Logseq 是否避开传统桌面 Electron 判断
  7. worker 是否带 openharmony=true
  8. SQLite WASM 是否能看到 WebAssembly
  9. 图谱创建 stage 是否全部通过
  10. 重启后图谱是否仍能恢复

这个顺序可以把 HAP 工程、资源目录、Electron 入口、前端环境判断、worker、SQLite 和持久化逐层拆开。


七、构建与运行方式

同步资源:

bash 复制代码
cd /logseq-master-ohos
pnpm ohos:sync

构建 HAP:

bash 复制代码
cd /logseq-master-ohos
pnpm ohos:build

HAP 输出目录:

text 复制代码
ohos_hap/electron/build/default/outputs/default/

当前构建生成的未签名 HAP:

text 复制代码
electron-default-unsigned.hap

构建时会先同步 Logseq Web release 资源,再查找 DevEco / Hvigor 和 OpenHarmony SDK,最后执行:

text 复制代码
hvigor assembleHap

实际输出中可能出现 Shadow CLJS、ArkTS 或权限相关 warning,只要 HAP 正常生成,并且设备侧不再出现 WebAssembly is not definednull.oo1SQLite WASM module is not ready 这类关键错误,就说明核心链路已经通过。


八、适配成果

logseq-master-ohos 已经完成:

  • 鸿蒙 Electron HAP 工程接入
  • Logseq Web release 资源构建与同步
  • resources/app/main.js 运行入口生成
  • 本地静态服务器加载 http://127.0.0.1:37910/
  • COOP / COEP / CORP 响应头补齐
  • OpenHarmony 运行环境标记注入
  • 避免误走传统桌面 Electron / Node IPC 路径
  • 浏览器侧 DB worker 路径接入
  • SQLite WASM 启动参数补齐
  • OpenHarmony 下 IndexedDB 图谱列表持久化
  • OpenHarmony 下 SQLite DB blob 兜底持久化
  • 图谱创建 stage 诊断
  • 原生窗口最小化、最大化、关闭按钮显示
  • 日记页、搜索弹层、基础编辑入口验证

九、功能验证结果

logseq-master-ohos 按知识库应用的核心路径完成了功能验证。

第一组是启动与页面:

  • HAP 可以安装并启动
  • 应用窗口标题显示 Logseq
  • 原生最小化、最大化、关闭按钮显示
  • 主界面不再停留空白
  • 日记页能够正常渲染

第二组是图谱与数据库:

  • 首次启动可以创建图谱
  • 图谱创建不再报 WebAssembly is not defined
  • SQLite 初始化不再出现 null.oo1
  • DB worker 可以进入 OpenHarmony 分支
  • 强停或关闭后重新打开,图谱可以恢复

第三组是交互:

  • 搜索按钮点击后能弹出搜索面板
  • 最近页面或搜索结果区域可以显示
  • 正文块可以进入编辑状态
  • 输入法可以被唤起
  • 光标和基础点击交互可用

第四组是日志检查:

  • 不再出现 SQLite WASM module is not ready
  • 不再出现图谱创建阶段的 WASM 缺失错误
  • 系统侧仍可能有剪贴板、输入法、GPU 相关 warning,但不影响 Logseq 主链路

十、结语

logseq-master-ohos 的适配本质上是一次"本地知识库 Web 内核鸿蒙承载"实践。

它和普通 Web 工具迁移最大的区别在于:Logseq 的核心不是页面,而是图谱和数据库。页面能显示只是第一步,真正决定可用性的,是 worker、SQLite WASM、存储、运行时判断和构建链路。

这次适配里最关键的转折点,是把"空白页""点击没反应""null.oo1"这类表象问题,拆成具体的图谱创建 stage,并最终定位到 WebAssembly is not defined。当错误变得足够具体以后,后续就可以通过运行参数、环境识别和持久化分支逐步解决。

第一阶段完成后,Logseq 已经可以在鸿蒙 Electron runtime 中完成启动、进入日记、创建图谱、打开搜索、进入编辑和恢复图谱这些核心动作。后续如果继续向完整桌面版靠拢,还需要处理附件路径、文件导入导出、插件系统、PDF 标注、白板性能、Logseq Sync、剪贴板权限以及更完整的本地文件系统能力。

对复杂软件迁移来说,这次经验比较清楚:

先让关键路径稳定闭环,再逐步扩大桌面能力边界。

Logseq 的鸿蒙适配第一阶段,基本就是沿着这条路线完成的。

相关推荐
枫叶丹42 小时前
【HarmonyOS 6.0】MDM Kit:PC/2in1设备用户行为限制策略详解
开发语言·华为·harmonyos
SuperHeroWu72 小时前
【HarmonyOS 7】鸿蒙应用 AI Coding 工具链 DevEco Code 到 DevEco CLI
人工智能·华为·ai编程·harmonyos·cli·code
祭曦念2 小时前
【共创季稿事节】鸿蒙原生 ArkTS 布局深度解析:Column 主轴对齐之 flex-start / center / flex-end 全解
华为·harmonyos
Davina_yu2 小时前
环境变量管理:Environment与LocalStorage的应用场景(23)
harmonyos·鸿蒙·鸿蒙系统
小鹏linux3 小时前
鸿蒙PC迁移:TupiTube Desk Qt 2D 动画工作室鸿蒙PC适配全记录
qt·华为·harmonyos
狼哥16863 小时前
防沉迷控制实战新特性接入
ui·华为·harmonyos
cfm_29143 小时前
JVM深度详解:Class常量池、运行时常量池、字符串常量池、包装类对象池
java·jvm
鸽芷咕3 小时前
鸿蒙PC迁移:LANDrop Qt 局域网传输工具鸿蒙PC适配全记录
qt·华为·harmonyos
祭曦念3 小时前
【共创季稿事节】鸿蒙原生ArkTS布局实战:PinchGesture捏合缩放 — 从入门到精通
华为·harmonyos