aps-agent/Tauri迁移可行性评估.md

7.8 KiB
Raw Permalink Blame History

Tauri 迁移可行性评估

评估日期:2026-09-02 · 基于 apps/desktop/ 现状代码(Electron 43.2.0 + electron-builder 26.15.3) 结论先行:技术可行,前端近乎零改动;真正的成本在 Rust 重写 sidecar 编排与离线升级体系(约 2,000 行久经测试的 JS),以及工厂离线 PC 的 WebView2 依赖风险。建议先做 1 周 PoC 再决策。


1. 现状资产盘点(需要迁移的东西)

文件 行数 Electron 耦合度 内容
main.cjs 659 🔴 高 窗口管理(自绘无边框)、单实例锁、15 个 IPC handler、~/.aps 目录布局、CSP 注入、导航守卫、nonce 请求头注入
sidecar.cjs 373 🟢 低(纯 Node) SidecarManager:端口预留、nonce/audit token 轮换、子进程环境白名单清洗(Conda/Python 隔离)、健康探测、日志轮转(10MiB)、崩溃重启策略(上限 3 次 + 退避)、taskkill 进程树回收、父进程看门狗
updater.cjs 570 🟢 无(纯 Node,注释明确写明无 Electron 依赖) 离线升级全流程:manifest 校验 → sha256 → 备份 → NSIS 静默安装 → 健康检查 + 版本比对 → 失败自动回滚 → 审计(本地 JSONL + 可选上报,含幂等键)
upgrade-nonce.cjs 337 🟢 无(纯状态机) 升级 nonce 续接协调器:pending 状态机(installing→verifying→verified/failed)、跨进程持久化、sidecar 重启后新 nonce 补验
preload.cjs 82 🔴 高 contextBridge 暴露 window.apsDesktop(约 20 个方法)
前端调用面 — — apsDesktop 仅 7 个文件、25 处调用(App.tsx、client.ts、AppMenuBar.tsx、SkillConsole.tsx 等)
测试资产 ~48 项 node 测试 + 2 个冒烟脚本(803 + 187 行) 🟡 中 updater/sidecar/nonce 单测是纯 Node 可保留逻辑用例;NSIS 真装冒烟与 electron-builder 布局强耦合

关键发现:项目最初的模块化做得不错——updater.cjs 和 upgrade-nonce.cjs 是纯 Node 无 Electron 依赖,逻辑可整体搬迁;但它们仍需用 Rust 重写(Tauri 主进程没有 Node 运行时)。

2. 逐项映射:Electron → Tauri

✅ 原生支持 / 几乎免费(约 40%)

能力 Tauri 对应 说明
前端复用 直接复用 apps/web/dist React 产物零改动
Python sidecar 官方 sidecar 机制(externalBin) PyInstaller 产物、aps-sidecar.spec 完全保留
无边框自绘窗口 decorations: false + data-tauri-drag-region 前端已有自绘顶栏(AppMenuBar),窗口控制走 @tauri-apps/api/window,无需 Rust
单实例锁 tauri-plugin-single-instance 官方插件
CSP 加固 tauri.conf.json 内置 CSP 字段 比 Electron 的 session 注入更声明式
权限拒绝 / 导航限制 Tauri webview 默认更封闭;外链走 opener 插件 安全姿态默认更好
中文菜单 现状已弃用原生菜单(web 顶栏呈现) 无需迁移
NSIS 安装包 Tauri v2 支持 NSIS target,兼容 /S 静默 离线升级触发语义可保持

⚠️ 需要适配 / 中等工作量(约 30%)

能力 迁移方式 风险点
apsDesktop 桥(25 处前端调用) 写一个 window.apsDesktop 兼容层封装 @tauri-apps/api,前端 7 个文件不改 低 —— 调用面小是最大利好
IPC handlers(15 个) 窗口类(min/max/close/fullscreen)前端直接调 JS API;其余(get-home / get-device-id / pick-directory / 升级三件套)写成约 6-8 个 Rust command 低
nonce 请求头注入 Electron 用 session.webRequest 拦截全部请求;Tauri 无此能力。替代方案:nonce 经桥暴露给前端,在 api/client.ts(已收口,仅 3 处调用面)统一注入 header 中 —— 安全模型微调:nonce 从"主进程持有、渲染进程不可见"变为"渲染进程可知"。实际暴露面等价(渲染进程本就能发带 nonce 的请求),但需安全评审确认
NSIS 冒烟脚本(803 行) Tauri NSIS 安装布局不同(无 win-unpacked、可执行文件名/路径变),脚本需适配重写 中 —— 脚本安全边界设计可复用

🔴 必须 Rust 重写(约 30%,成本集中在这里)

模块 重写估算 说明
SidecarManager(373 行 JS) ~600 行 Rust,1-2 周 端口预留、nonce 轮换、环境白名单清洗(Conda/Python 隔离逻辑微妙,测试用例多)、健康探测、日志轮转、重启退避、taskkill 进程树、父进程看门狗。Tauri sidecar 只负责"拉起",编排全部自建
Updater(570 行 JS) ~800 行 Rust,2-3 周 Tauri 官方 updater 插件面向在线签名更新,不适配本项目的 U 盘/介质离线升级 + manifest + 备份回滚 + 幂等审计流程,必须整体重写
upgrade-nonce 协调器(337 行 JS) ~400 行 Rust 建议与 Rust 版 SidecarManager 合并(重启事件在同进程内,不再需要跨模块事件总线),可适度简化
测试体系重建 1 周 48 项 node 测试逻辑用例可翻译成 Rust 单测;打包冒烟(CDP 冒烟是 Electron 专属,需找 Tauri 等价手段或放弃)

3. 风险清单(按严重度)

# 风险 严重度 说明与缓解
R1 WebView2 依赖 vs 工厂离线 PC 🔴 高 Electron 自带 Chromium 零依赖;Tauri 依赖系统 WebView2。工厂现场老 Win10/离线机器可能没有。缓解:Tauri NSIS 支持内嵌 WebView2 离线引导(embedFixedWebview2,体积 +100MB 左右,会吃掉约一半的体积收益)。这是决策的第一道门:先调查目标客户的机器现状
R2 升级链路重写重新打开安全验证面 🟡 中高 updater + nonce 协调器是经过 round-43~48 多轮加固、48 项测试、真装冒烟验证的资产。重写后所有边界场景(nonce 过期不误回滚、安装途中 sidecar 重启、应用重启续接)需重新验证
R3 团队 Rust 能力 🟡 中 约 1,800 行 Rust 新增代码,含进程管理、文件哈希、Windows API(taskkill 等价)
R4 体积收益被 sidecar 稀释 🟡 中 567MB 解包中 Electron 壳约占 250-300MB,Python sidecar 占其余大头。换 Tauri 后安装包预计从 ~180MB 降至 ~60-80MB——有感知但不是数量级
R5 过渡期双壳维护 🟢 低 PoC 期间 Electron 继续演进,需冻结桌面安全需求或接受两次实现

4. 工作量估算

里程碑 内容 工期
M0 PoC Tauri 壳 + web dist + sidecar 拉起 + 健康探测 + 兼容桥跑通主界面 3-5 天
M1 Rust 版 SidecarManager 完整对齐(环境清洗/重启/日志/看门狗)+ 单测 1-2 周
M2 IPC command + 窗口态 + 单实例 + CSP + nonce header 方案落地 3-5 天
M3 Rust 版离线 Updater + nonce 协调器 + 测试翻译 2-3 周
M4 打包链路(NSIS/SBOM/冒烟)+ 验证矩阵重跑(冷启动/Defender/升级回滚/中文路径) 1-2 周
合计 PoC 1 周内可见证;全量对齐约 6-9 周(1 人)

5. 决策建议

第一道门(先做):目标客户机器 WebView2 现状调查
  ├─ 现场 Win10/11 均有 WebView2(或可联网/可预装)
  │    → 启动 M0 PoC(1 周),跑通则排期 6-9 周全量迁移
  └─ 大量离线老机器无 WebView2
       → 维持 Electron,转向"瘦身"替代方案:
         ① sidecar onedir 裁剪(排除未用包,通常可省 100MB+)
         ② electron-builder asar 压缩 + NSIS 高压缩
         ③ 移除安装包中未用的 Chromium 语言包/locales

不建议在升级链路(R2)没有完整测试覆盖前双壳并行发布;迁移应一次性切换、单壳维护。