5.8 KiB
5.8 KiB
Electron 客户端 Review(2026-02)
1. 已做修正
1.1 Windows CI 上传步骤
- 问题:
Upload artifacts to Release使用 bash 语法,Windows runner 默认 shell 为 PowerShell,会导致上传失败。 - 修正:为该 step 增加
shell: bash,三平台统一用 bash 执行上传脚本。
2. 架构与脚本
2.1 打包脚本(package.json)
- dist:mac / dist:win / dist:linux:单平台、Mac 走签名/公证(需证书与 env)。
- dist:mac:unsigned:仅 Mac、无签名,用于无证书环境。
- dist:unsigned:local:当前平台无签名,避免在 Mac 上同时打 Win/Linux 时的 node-gyp 交叉编译。
- dist:all / dist:unsigned:一次传
--mac --win --linux,在 arm64 Mac 上会因 better-sqlite3 交叉编译失败,仅适合在无 native 依赖或非交叉编译场景使用;当前推荐用 CI 分平台打。
2.2 prepare 脚本
- prepare:uv:多平台,从 GitHub 下载或使用已有 uv,正常。
- prepare:sign-uv:仅 macOS 执行签名,其他平台跳过,正常。
- prepare-lanproxy:缺二进制时改为仅警告 + 创建目录,不
process.exit(1),CI 可正常产出 Win/Linux 安装包,该平台下 lanproxy 功能不可用。 - prepare-sdk:若
vendors/qimingcode-sdk不存在则process.exit(0);若仓库未包含或未 clone 该路径,后续 electron-builder 可能因file:依赖或符号链接报错,需保证 CI 与本地均有该目录(或等效依赖)。
2.3 主进程 import 路径
- 已按
tsconfig.main.json的 rootDir 修正:acpClient、engineManager、unifiedAgent、dependencies中对constants/@shared/constants的相对路径,build:main可正常通过。
3. CI(release-electron.yml)
- 触发:tag
electron-v*,与 Tauri 的v*分离,设计合理。 - prepare:解析版本、读取 release notes、创建 Release,逻辑清晰。
- build-electron:matrix 三平台(macos / windows / ubuntu),各跑对应
dist:*,fail-fast: false 可接受。 - macOS:可选导入证书与公证 key,未配置时走
dist:mac:unsigned,合理。 - 上传:已改为
shell: bash,Windows 上也可正确执行。
4. 风险与建议
| 项 | 说明 |
|---|---|
| vendors/qimingcode-sdk | 若未提交或 CI 未包含,prepare-sdk 会跳过,可能导致构建或打包失败。建议:CI 确保该路径存在或使用可选的 file 依赖策略。 |
| lanproxy 缺失 | 已做:主进程返回友好错误文案;新增 lanproxy:isAvailable IPC;设置页在无二进制时展示「当前平台暂不支持内网穿透」并禁用启动。 |
| dist:unsigned:local 语义 | 当前为「当前平台 + 无签名」。若希望本地默认走签名,保留 dist:mac 为默认 Mac 打包方式即可;dist:unsigned:local 明确为「快速无签名构建」即可。 |
| Release 已存在 | 当前逻辑为 gh release view 存在则只打印 "Release already exists" 不报错,后续上传会覆盖同名的 asset(--clobber)。若需避免覆盖,可改为上传前检查或使用不同 artifact 名称。 |
5. 日志设计(logConfig)
5.1 实现要点
- logConfig.ts:
initLogging()在 main 入口最早调用,设置 electron-log 的 file transport:路径、maxSize、level、自定义archiveLogFn(轮转时重命名为main.YYYY-MM-DD-HHmmss.log),并在启动时执行 TTL 清理。 - 开发 vs 正式:
isDev()用!app.isPackaged与NODE_ENV判断;开发 5MB/30 天、正式 2MB/7 天,文件级别分别为 debug / info。 - cleanupOldLogs:只删
main/renderer的.old.log与.YYYY-MM-DD-*.log,不删main.log、renderer.log及其他文件(如 app.json、mcp/ 等)。
5.2 审查结论
- 轮转与 TTL 逻辑清晰,归档命名可区分且便于按时间删除。
archiveLogFn内调用log.info会写入当前 main.log(轮转后为新文件),不会造成递归轮转。- 已扩展 TTL 清理:对同一 logDir 下的
renderer.old.log、renderer.YYYY-MM-DD-*.log应用相同 TTL,与 main 归档一并清理。 - LOGGING.md 已说明目录、行为与配置入口。
5.3 latest.log 统一入口(多平台)
- 实现:
updateLatestLog(logDir)在 init 结束时通过setImmediate调用(保证 main.log 已存在);轮转时仅在 Windows 下通过setImmediate再次调用,因硬链接指向 inode 需重新指向新 main.log。 - macOS/Linux:
fs.symlinkSync('main.log', latestPath, 'file'),相对路径,轮转后无需更新。 - Windows:
fs.linkSync(mainPath, latestPath)硬链接,无需管理员/开发者模式;轮转后 setImmediate 时新 main.log 已由 transport 同步写入,时序正确。 - log:list:优先读
latest.log,不存在则回退getFile().path;log:getDir/log:openDir仍为目录,用户打开目录后可见latest.log。 - cleanupOldLogs 不删
latest.log(isArchiveLogName不匹配),符合预期。 - 可选改进已做:
log:openDir在 macOS 上open -R <latest.log>、在 Windows 上explorer /select,<latest.log>,打开目录并选中当前日志入口;失败时回退为仅打开目录;Linux 仍为仅打开目录。
6. 文档与约定
- SIGNING.md:记录 Mac 签名/公证与 env,便于本地与 CI 配置。
- release-notes/:支持
release-notes/electron-v<version>.md作为 Release 说明,与 workflow 一致。 - 应用名与目录:使用
APP_DISPLAY_NAME/APP_NAME_IDENTIFIER(及APP_DATA_DIR_NAME)统一,避免硬编码.qimingclaw/qiming-agent。 - LOGGING.md:日志轮转、TTL、开发/正式差异说明。
Review 完成;Windows 上传步骤已修正;日志设计与 latest.log 多平台方案已纳入审查。