mcpField
E
electron-wrapper

electron-wrapper

github.com/brianlovin开发379120 次安装31 周前更新
代码仓库

关于 electron-wrapper

为现有 Bun Web 应用提供封装为 Electron 桌面应用的实施指南,覆盖主进程、预加载桥接、应用适配与构建发布。适用于希望保留 Web 服务逻辑,同时增加原生窗口和系统功能的开发者。

主要功能

  1. 01Electron 与 Bun 双运行时架构
  2. 02启动 Bun 服务并加载本地页面
  3. 03预加载桥接与 IPC 管理
  4. 04Web 应用适配 Electron 环境
  5. 05构建、签名与 CI 发布指导

适用场景

  1. 01将现有 Bun Web 服务封装为桌面应用
  2. 02为应用添加窗口管理和原生菜单
  3. 03配置 Electron 桌面应用的构建与发布流程

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/brianlovin/agent-config --skill electron-wrapper

安装后在 Claude Code 中输入/electron-wrapper确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
build-and-distribute.md
main-process.md
pitfalls.md
project-setup.md
web-adaptation.md

详细介绍

Bun Web 应用的 Electron 封装

本技能将指导你使用 Electron 把现有的 Bun Web 服务器封装为原生桌面应用。它基于经过验证的实现,解决了所有主要集成难题。

架构

“Electron 负责外壳,Bun 负责服务”——两个运行时协同工作:

  • Electron/Node.js 负责窗口管理、原生菜单、自动更新和 IPC
  • Bun 运行实际的 Web 服务器及所有应用逻辑

Electron 主进程会启动打包后的 Bun 二进制文件来运行服务器,然后在 BrowserWindow 中加载 http://localhost:{port}。你的 Web 应用无需知道或关心自己运行在 Electron 中——它只是一张网页,还可以选择使用 window.electronAPI 桥接原生功能。

这种架构意味着:

  • 无需更改服务器代码(它仍是标准的 Bun HTTP 服务器)
  • Web 应用在浏览器和 Electron 中的运行方式完全相同
  • Electron 只处理浏览器无法完成的任务:窗口外框、系统托盘、自动更新、文件系统访问
  • 使用两个独立的 node_modules——Electron 使用 npm,Web 应用使用 Bun

第 1 阶段:项目设置

在现有 Bun Web 应用旁创建 Electron 子项目。

需要创建的内容:

  • electron/ 目录,其中包含独立的 package.json(使用 npm,而非 Bun)、两个 tsconfig(主进程使用 ESM,预加载使用 CJS)、electron-builder.yml 和 macOS 权限配置
  • 用于打包服务器的 scripts/build-server.ts
  • 用于下载特定平台 Bun 二进制文件的 scripts/download-bun.ts
  • 父项目中的更改:新增脚本、tsconfig 排除项和 .gitignore 条目

参考:project-setup.md

第 2 阶段:主进程

构建 Electron 主进程——包括入口点、服务器启动、窗口管理、自动更新器和预加载桥接。

需要创建的文件:

文件用途
electron/src/main/index.ts应用生命周期、开发/生产模式、单实例锁、IPC 处理器
electron/src/main/bun-server.ts启动打包后的 Bun、选择端口、轮询健康状态、注入环境变量
electron/src/main/window.tsBrowserWindow 配置、窗口边界持久化、安全设置、导航防护
electron/src/main/updater.tselectron-updater 设置、将事件转发给渲染进程
electron/src/preload/index.ts使用 invoke/on 模式并支持取消订阅的 contextBridge API

关键决策:

  • 开发模式使用 ELECTRON_DEV_URL 环境变量连接外部开发服务器(不在内部启动 Bun)
  • autoDownload: false——让用户选择何时下载更新
  • 预加载脚本只公开特定方法,绝不公开原始 ipcRenderer
  • 使用 electron-store 持久化窗口边界

参考:main-process.md

第 3 阶段:Web 应用适配

调整现有 Web 应用,使其能够检测并响应 Electron 环境,同时仍可作为独立 Web 应用正常运行。

Web 应用需要进行的更改:

更改详情
Electron 检测工具isElectron()、getElectronPlatform()、isMacElectron()、applyElectronDocumentAttributes()
类型声明将 window.electronAPI 的所有属性设为可选
CSS 拖拽区域.app-window-drag/.app-window-no-drag 类,自动排除交互元素
交通灯间距--electron-traffic-left CSS 变量(macOS 上为 72px,其他平台为 0px)
存储路径使用环境变量指定数据目录,并在未设置时回退到 CWD
静态资源服务在生产模式下使用环境变量指定静态资源目录
自动更新钩子提供下载/安装控制功能的 useElectronUpdater() React 钩子
更新通知显示“可用 → 正在下载 → 就绪”状态的胶囊组件
功能门控在 Electron 中禁用演示模式和托管功能

参考:web-adaptation.md

阶段 4:构建与分发

打包所有内容、设置 CI/CD 并处理代码签名。

构建流水线:

  1. 构建 Web 应用(bun run build)
  2. 将服务打包为单个文件(Bun.build() → resources/server/index.js)
  3. 下载特定平台的 Bun 二进制文件 → resources/bun/{platform}-{arch}/
  4. 编译 Electron TypeScript(分两次:主进程 ESM + 预加载 CJS)
  5. electron-builder 使用 extraResources 打包所有内容

CI/CD:

  • GitHub Actions 由版本标签触发(例如 v*、clippy-v*)
  • 矩阵构建:在 macos-14 上构建 macOS arm64/x64,在 windows-latest 上构建 Windows x64
  • 构建步骤中使用 --publish never,单独的发布任务会创建 GitHub 草稿版本
  • 在 CI 中导入 Apple 证书并进行公证

代码签名:

  • macOS:Developer ID Application 证书,导出为 base64 .p12
  • 通过 Apple ID + app 专用密码进行公证
  • 需要 5 个 GitHub 密钥:APPLE_CERTIFICATE、APPLE_CERTIFICATE_PASSWORD、APPLE_ID、APPLE_PASSWORD、APPLE_TEAM_ID

图标:

  • macOS:使用 sips + iconutil 将源 PNG 转换为 .icns
  • Windows:使用 png-to-ico npm 包转换为 .ico

参考:build-and-distribute.md

发布版本

**切勿在本地构建发布产物。**CI 拥有签名证书和公证凭据。本地构建会生成未签名的应用,macOS Gatekeeper 会阻止其运行。

发布工作流:
  1. 在 electron/package.json 中更新版本号,提交更改并合并到 main
  2. 查找 CI 工作流所需的标签格式:
    grep -A2 'tags:' .github/workflows/*.yml
    
  3. 为 main 上已合并的提交打标签:
    git tag <pattern><version> origin/main
    git push origin <pattern><version>
    
  4. 监控 CI:
    gh run list --workflow=<workflow>.yml --limit=1
    
  5. 在 GitHub 上审核并发布草稿版本
常见错误:
  • 在本地运行 electron-builder --publish always——不会进行公证
  • 使用 gh release create 和本地构建产物——未签名
  • 在版本号更新合并前打标签——构建使用的版本号不正确
  • 为功能分支而非 origin/main 打标签

完整详情请参阅 pitfalls.md §13。

关键注意事项

快速参考列表——症状和代码示例详见 pitfalls.md。

#注意事项一句话修复方法
1ESM/CJS 冲突设置 "type": "module",并对 CJS 包使用默认导入模式
2预加载脚本必须使用 CJS使用单独的 tsconfig,并设置 "module": "CommonJS"
3__dirname 不可用使用 fileURLToPath(import.meta.url) 填充实现
4开发模式 MIME 错误通过 ELECTRON_DEV_URL 连接到外部开发服务
5Bun 版本不匹配在下载脚本中固定版本,并与开发环境版本保持一致
6nvm PATH 问题对生成的进程使用 bash -lc
7存储路径错误使用环境变量 + app.getPath("userData")
8打开时出现白屏使用 show: false + ready-to-show + 深色 backgroundColor
11${platform} ≠ process.platform将 Bun extraResources 放在 mac:/win: 部分中,并使用 darwin-/win32- 前缀
12Bun 工作区会提升依赖使用 esbuild + createRequire banner 打包主进程,或对 electron 目录使用 npm
13本地构建不会进行公证始终通过 CI 标签发布,切勿在本地使用 electron-builder --publish

开发工作流

electron:dev 命令会运行完整的开发环境:

npm run dev
  ├── concurrently
  │   ├── dev:web    → cd .. && bun run dev          (Bun dev server with HMR)
  │   └── dev:electron
  │       ├── wait-on http://localhost:3005           (wait for dev server)
  │       ├── npm run build                           (compile TS)
  │       └── ELECTRON_DEV_URL=... electron .         (launch Electron)
  • Web 开发服务会运行 HMR——更改会立即生效
  • Electron 会连接到开发服务,而不是启动自己的 Bun
  • 修改预加载脚本和主进程后,需要重启 electron:dev
  • Web 应用的更改会自动热重载

若要在本地测试接近生产环境的行为:

bun run electron:pack    # builds everything, packages without installer
# Output in electron/release/

自定义检查清单

将此项目改用于新项目时,请更新以下项目专属值:

  • electron-builder.yml 中的应用名称(productName、appId)
  • window.ts 中的窗口标题
  • dev:electron 脚本和 dev 脚本中的开发服务器端口
  • 环境变量名称(例如,APP_DATA_DIR、APP_STATIC_DIR)
  • 窗口配置中的 backgroundColor,使其与应用主题相匹配
  • electron-builder.yml 的 mac 部分中的 category
  • electron/package.json 中的仓库 URL
  • download-bun.ts 中的 Bun 版本
  • electron/assets/ 中的图标资源

评论

支持 Markdown