翻译:Electron 与 Tauri 对比:为 Dolt Workbench 选择桌面应用框架

110 阅读6分钟

以下是博客文章Electron vs. Tauri的中文翻译:


Electron 与 Tauri 对比:为 Dolt Workbench 选择桌面应用框架

Dolt Workbench 是一个开源的 SQL 工作台,支持 MySQL、PostgreSQL、Dolt 和 Doltgres 数据库。我们使用 Electron 构建了这个工作台——Electron 是一个流行框架,可以将使用 HTML、CSS 和 JavaScript 等传统 Web 技术构建的 Web 应用转换为桌面应用。由于 Workbench 与 DoltHub 和 Hosted Dolt 有很多共通之处,因此其架构与这些产品非常相似:前端使用 Next.js,并额外引入了一个用于处理数据库交互的 GraphQL 层。正因如此,使用 Electron 来快速构建桌面版应用是一个顺理成章的选择。

然而,随着 Workbench 日趋成熟,Electron 的一些显著缺点也开始显现。因此,我花了一些时间调研 Tauri —— 一个较新的、同样支持“Web 转桌面”应用场景的框架。在这篇文章中,我们将探讨 Electron 和 Tauri 与 Workbench 的集成效果,并对它们各自的优缺点进行比较。


Next.js 支持情况

Next.js 在桌面应用环境中表现并不理想,这主要是由于其围绕 服务端渲染(SSR)API 路由 的架构设计。在桌面应用中,并不存在一个客户端与服务端交互的服务器;我们只需要在窗口中渲染 HTML、CSS 和 JavaScript。因此,Electron 对 Next.js 应用的支持相当有限。

这并不是说你不能用 Next.js 构建 Electron 应用,但确实需要一些变通方法。其中一个较流行的方案是名为 Nextron 的项目,其目标是将 Next.js 应用连接到 Electron 框架,并简化构建流程。我们在 Workbench 中就使用了 Nextron。然而,截至本文撰写之时,Nextron 似乎已不再维护,我们也开始在使用中遇到一些问题。

相比之下,Tauri 对前端框架基本是中立的。对于 Next.js,虽然你仍然无法使用其服务端功能,但 Tauri 通过利用 Next.js 的 静态站点生成功能(Static Site Generation),使集成过程变得简单得多。只需在 Next.js 配置文件中设置 output: 'export',Tauri 就能自动处理其余部分。


Web 视图(Webview)差异

Electron 与 Tauri 最大的区别在于 UI 渲染方式

Electron 在应用中打包了完整的 Chromium 浏览器引擎(与 Google Chrome 使用的引擎相同)。这确保了开发者无需担心浏览器兼容性问题——无论用户使用什么设备或系统架构,应用界面始终由相同的 Chromium 实例渲染,从而提供高度一致的体验。但代价是显著的 体积膨胀:即便是最简单的“Hello World” Electron 应用,安装包也可能高达 150MB

Tauri 则通过利用系统自带的原生 Webview 来解决这个问题。它使用一个名为 WRY 的跨平台库,为不同操作系统提供相应的 Webview 接口。这使得 Tauri 应用极为轻量。缺点在于,你失去了对浏览器兼容性的硬性保障。不过在实践中,这种兼容性问题几乎不会出现,尤其是在主流操作系统上。


Node.js 与 Rust 的对比

另一个关键差异在于 主进程(main process) 的实现方式。主进程负责管理应用窗口、菜单以及其他需要调用系统 API 的部分。

  • Electron 的主进程运行在 Node.js 环境中,这意味着你可以直接使用所有 Node.js API,以纯 JavaScript 编写 Electron 特定代码。这对 Web 开发者非常友好。
  • Tauri 的主进程则使用 Rust 语言编写。这无疑提高了门槛,但 Tauri 提供了一套相当完善的 JavaScript API,用于与底层 Rust 交互。在绝大多数场景下,这些 API 已足够使用。在 Workbench 的迁移过程中,我仅需少量 Rust 代码和 Tauri 提供的 JS API,就完整复现了 Electron 版本的所有功能。

从使用体验来看,我认为 Tauri 的 API 更自然地融入了我们的应用代码。在 Electron 中,即使是最简单的操作(比如写入本地文件),也必须通过 进程间通信(IPC):前端先发信号给主进程,主进程再执行文件写入。而在 Tauri 中,你可以直接调用其文件系统 API,虽然底层依然使用 IPC,但抽象更简洁、直观。


侧载服务(Sidecars)

Electron 打包时会附带完整的 Node.js 运行时,这有利有弊。

对于 Workbench 而言,这是一个优势:因为我们的 GraphQL 层本身就是一个独立的 Node.js 应用,需要与前端并行运行。由于 Electron 已包含 Node.js,我们可直接从主进程中启动 GraphQL 服务,省去了打包和运行额外“侧载服务”的麻烦。

例如,Workbench 还内置了 Dolt 二进制文件,允许用户从应用内直接启动本地 Dolt 服务器。我们为每个架构单独打包对应的 Dolt 可执行文件。如果没有 Node.js 运行时,我们就必须对 GraphQL 层也采取类似处理。

而 Tauri 正好面临这个挑战。解决方案是:使用如 pkg 这样的工具,将 GraphQL 服务编译成独立二进制文件,再作为侧载服务运行——这正是 Tauri 官方文档中推荐的做法,且已有详细指南。

值得一提的是,完整的 Node.js 运行时非常臃肿,也是 Electron 应用体积庞大的原因之一。在分别用 Electron 和 Tauri 构建 Workbench 后,体积差异十分显著(左为 Electron,右为 Tauri):

Electron vs. Tauri 应用体积对比


当前限制

尽管我们已成功在 Tauri 中复现 Workbench 的全部功能,但目前仍暂缓全面迁移,原因如下:

  • Windows 平台缺少 .appx / .msix 支持:Tauri 目前仅支持生成 .exe.msi 安装包。这意味着无法通过 Microsoft Store 分发打包应用。而 Workbench 当前正是通过 .appx 格式上架商店。若切换至 Tauri,我们必须下架现有应用,并以 .exe 格式重新上架。
  • macOS 通用二进制(Universal Binary)问题:这更多是使用上的不便。Tauri 似乎无法将 arm64 与 x64 构建产物合并为 macOS 通用二进制,且存在重复签名(codesign)的问题。

这两个问题都不是硬性障碍,但足够令人头疼。因此,在 Nextron 问题变得更严重之前,我们暂不迁移。目前迁移分支已保留,待上述问题解决后再行推进。如果你来自 Tauri 团队,欢迎提供解决方案!


结语

总体而言,我对 Tauri 印象深刻。它有效消除了 Electron 的臃肿问题,并能自然地集成到我们的现有代码库中。如果你对 Tauri 或 Dolt Workbench 感兴趣,欢迎加入我们的 Discord 交流!