打包

使用 electron-builder 为 macOS、Windows 与 Linux 构建安装包。

对桌面应用而言,"部署"意味着产出安装包,以及(可选地)托管一个更新源 ——没有 Web 主机。本页讲用 electron-builder 为每个平台构建带签名的安装包;更新源 见自动更新

构建流水线

每个平台的构建都是两步,由 package.json 脚本串起来:electron-vite build 把 三个包编译进 out/,随后 electron-builder 把它们打包成 dist/ 下的安装包。

pnpm build:mac      # run-s vite:build:app electron:build:mac
pnpm build:win      # → NSIS 安装包
pnpm build:linux    # → AppImage + snap + deb
pnpm build:unpack   # vite 构建 + electron-builder --dir(快速,不出安装包)

迭代时用 pnpm build:unpack 做快速本地检查——它产出一个未打包的应用目录而不 构建安装包,因此快得多。

只能在对应平台上(或合适的 CI runner 上)构建该平台的安装包。macOS 构建需要 macOS;Linux 的 snap 目标需要 Linux。别指望 pnpm build:win 能在 macOS 上 产出可用的带签名 Windows 安装包。

electron-builder.yml

配置小而声明式。关键字段:

appId: com.soarstarter.electron      # 来自 shared/constants 的 APP_ID
productName: soar-electron           # PRODUCT_SLUG
asar: true                           # 应用打入归档
asarUnpack: [resources/**]           # 资源留在磁盘上(图标、钩子)
protocols: [{ name: Soar Electron, schemes: [soar-electron] }]
files: [out/**, resources/**, package.json]
npmRebuild: false

各平台目标:

mac:
  hardenedRuntime: true
  gatekeeperAssess: false
  entitlements: resources/build/entitlements.mac.plist
  extendInfo:
    - NSCameraUsageDescription: ...
    - NSMicrophoneUsageDescription: ...
    - NSDocumentsFolderUsageDescription: ...
    - NSDownloadsFolderUsageDescription: ...
  notarize: false          # 改由 afterSign 钩子公证
dmg:
  artifactName: ${name}-${version}.${ext}

DMG 形式发布。硬化运行时(hardened runtime)+ 授权项是公证的前提。

win:
  executableName: soar-electron
nsis:
  artifactName: ${name}-${version}-setup.${ext}
  shortcutName: ${productName}
  createDesktopShortcut: always

NSIS 安装包形式发布。

linux:
  target: [AppImage, snap, deb]
  maintainer: Soar Starter
  category: Utility
appImage:
  artifactName: ${name}-${version}.${ext}

发布 AppImage + snap + deb。把目标列表裁剪到你实际分发的那些。

代码签名

签名由环境变量驱动,未设置时跳过,因此无凭据的构建总能成功(未签名)。提供 这些密钥——通常作为 CI 密钥——即可产出带签名的产物。

签名使用登录钥匙串里的 Developer ID 证书。公证由环境变量驱动的 afterSign: resources/build/notarize.cjs 钩子执行,它读取 APPLE_IDAPPLE_APP_SPECIFIC_PASSWORDAPPLE_TEAM_ID,并在未设置时空操作。 electron-builder 内置的 notarize 刻意保持 false,使无凭据构建不会失败。

APPLE_ID=you@example.com
APPLE_APP_SPECIFIC_PASSWORD=abcd-efgh-ijkl-mnop
APPLE_TEAM_ID=ABCDE12345

仅当存在 CSC_LINK(PFX/P12 路径或 base64 数据)与 CSC_KEY_PASSWORD 时, electron-builder 才对安装包签名。

CSC_LINK=./cert.pfx
CSC_KEY_PASSWORD=••••••

未签名的 Windows 构建能运行,但在证书积累下载信誉之前 SmartScreen 会向用户 告警——EV 证书可立即消除此提示。

Linux 包通常不签名;无需额外配置。

更新源 URL

electron-builder.env 保存着打包时 publish.url 读取的发布 URL:

UPDATE_SERVER_URL=https://example.com/auto-updates

在构建你打算发布的版本之前,把它指向你托管更新源的位置。详见 自动更新

图标与用途字符串

electron-builder 会按平台自动探测 resources/build/icon.{icns,ico,png}——没有 显式的 icon 字段。要给图标改品牌,编辑两个源 SVG,并用 docs/APP_ICONS.md 中的步骤重新生成每个位图(使用 macOS 的 sips/iconutil + png-to-ico,无需 ImageMagick)。另见品牌定制

extendInfo 中的 macOS NS*UsageDescription 字符串声明了应用为何可能请求 摄像头、麦克风、文稿与下载访问。把你的应用用不到的那些删掉——一个你从不触发 的用途字符串是无用的元数据(并注意渲染进程的权限处理器默认拒绝这些;参见 窗口、菜单与托盘)。

构建前的质量门

打包任何东西之前,先跑 AGENTS.md 的质量门:

pnpm lint:check && pnpm typecheck && pnpm test

对于发布构建,还要跑打包烟测与包体分析:

pnpm test:smoke        # Playwright 针对已构建应用,VITE_E2E_BYPASS_AUTH=true
pnpm analyze:bundle

VITE_E2E_BYPASS_AUTH 是一个仅供测试的标志,用于在烟测中绕过认证门。切勿 在真实构建中设置它——参见环境变量

相关页面

On this page