打包、签名与分发
连接构建产物、平台格式、签名、公证和资源布局。
本页整合 Electron 归档分稿中的机制、接口和接线。归档使用 Electron 44 系列作为其版本讨论背景;本文接口依据官方文档及 breaking changes 核查,实际采用时仍需固定项目版本。包版本、维护状态和原稿实测均是对应日期的历史信息。本次未启动 Electron、构建安装包、签名、公证或验证更新。代码块按各自标注区分片段与组合示例。
调研时间:2026-10-04。文中版本号、默认值均来自原调研当日记录(npm registry)与所列官方文档原文;无法核实处已标注「待核实」。
8.1 原理与机制:Electron 应用如何变成安装包
Electron 应用 = Electron 运行时(Chromium + Node.js)+ 你的应用代码。打包工具做的事情本质上是四步:
- 复制与重命名运行时:把对应平台的 Electron 预编译产物取出,替换图标与
Info.plist/版本资源,做成「你的」.app/.exe/AppImage; - 打包应用代码进 asar:应用源码默认打进
app.asar归档(见 8.5),native 模块的.node文件等留在app.asar.unpacked; - 代码签名:macOS 用
codesign(Developer ID),Windows 用 Authenticode/Azure Artifact Signing; - 封装安装器:macOS 封
dmg/pkg,Windows 封 NSIS/MSI/MSIX,Linux 封 AppImage/deb/rpm/snap 等,并生成自动更新所需的元数据与 blockmap。
代码签名把发布者身份与产物完整性接入平台的安全检查。面向普通用户分发时,需要按目标系统和渠道准备签名;缺少签名、公证或足够信誉,可能触发 Gatekeeper、SmartScreen 的提示或组织策略阻止。具体结果受来源、系统版本、证书与管理策略影响。macOS 公证检查已知恶意内容,也需要与签名、下载隔离属性一起验证(见 8.4)。
两个事实在 2025-2026 发生了变化,直接影响打包策略(来源:@electron/packager README):从 Electron 44.0.0-alpha.4 起,官方不再发布 Windows ia32 与 Linux armv7l 构建(仅 Electron ≤ 43 提供);且 @electron/packager 要求 Node.js ≥ 22.12.0。另外,macOS 的 .app 只能在 macOS 主机上签名(同来源),CI 需 macOS runner。
8.2 electron-builder vs Electron Forge(2026)
官方定位:Electron 官方文档主推 Forge,并把 electron-builder 列为社区维护的第三方工具——"These tools are maintained by members of the Electron community, and do not come with official support from the Electron project"、"electron-builder replaces features and modules used by the Electron maintainers (such as the auto-updater) with custom ones"(electronjs.org forge-overview)。Forge 自己的对比页则指出哲学差异:"Forge focuses on combining existing first-party tools into a single build pipeline, while Builder rewrites its own in-house logic",并认为 Forge 优势在于新特性第一时间跟进(如 ASAR integrity、universal macOS builds)与多包架构更易扩展(electronforge.io)。
| 维度 | Electron Forge | electron-builder |
|---|---|---|
| 维护方 | Electron 官方组织 | electron-userland 社区(netlify 维护者为主) |
| 版本(2026-10-04 实测) | @electron-forge/cli 8.0.1 | npm latest 26.15.3、v26 tag 26.17.0;next 27.0.0-alpha.9(v27 仍为 alpha) |
| 底层 | 组装 @electron/packager + @electron/osx-sign + @electron/notarize + @electron/windows-sign | 自有 app-builder-lib 流水线 |
| 配置形态 | forge.config.js(makers/publishers/plugins) | package.json 的 build 字段或 electron-builder.yml |
| 脚手架 | npm init electron-app 官方模板(Vite/webpack) | 无(自带构建体系) |
| Windows 产物 | Squirrel.Windows、MSI(WiX)为主 | NSIS/NSIS-web/portable/MSI/MSI-wrapped/AppX/MSIX(beta)/Squirrel(官方标注 legacy) |
| Linux 产物 | zip、deb、rpm、snap、flatpak(视 maker) | AppImage/deb/rpm/snap/flatpak/pacman(beta)/apk/freebsd/p5p/zip/tar.gz |
| 自动更新 | 官方 autoUpdater(Squirrel)+ update.electronjs.org | electron-updater(blockmap 差量下载、generic/S3 等私有 feed) |
| 签名 | 统一 windowsSign / osxSign / osxNotarize | 自有签名实现 + win.azureSignOptions |
两者现已可混合:electron-builder 发布了 Forge maker 包(electron-forge-maker-nsis、-nsis-web、-appimage、-snap),但官方明确其限制——"Publishing, Auto Update, and Code Signing are only available when using electron-builder as your primary build tool"(electron.build 文档)。
electron-builder 的典型配置(electron-builder.yml,集中体现签名、公证、压缩与产物选择):
appId: com.acme.app
compression: normal # store | normal(默认) | maximum
mac:
target: [{ target: dmg, arch: [arm64, x64] }, { target: zip, arch: [arm64, x64] }]
notarize: true # 公证开关;签名项 v27 起移入 mac.sign
sign:
hardenedRuntime: true
entitlements: build/entitlements.mac.plist
win:
target: [nsis] # 默认;企业场景另出 msi
azureSignOptions: { certificateProfileName: acme } # Azure Artifact Signing
nsis:
oneClick: true # 默认值
differentialPackage: true # 默认值;可选 "store-asar"
linux:
target: [AppImage, deb, rpm]
electronLanguages: [zh-CN, en-US] # 裁剪 Electron locale
publish: { provider: generic, url: https://cdn.example.com/update/ }本分册采用:新项目、希望与官方工具链(含 Electron 安全公告、fuses、ASAR integrity)保持同步、能接受官方 autoUpdater 模型 → Forge;需要最全的安装器矩阵、私有化更新 feed、blockmap 差量下载、深度定制 NSIS/dmg → electron-builder(consciously 接受"非官方支持"这一前提,这也是 Fora Soft 等外包团队的普遍选择)。存量大型项目(VS Code、Slack、Discord 等)多有自研管线,不必对齐任一工具。
8.3 各平台产物格式与选择
macOS:dmg / pkg / zip / mas / universal
- dmg:消费级分发标准,拖拽安装;zip:不是给用户的,是
electron-updater的更新 payload(比 dmg 小);pkg:需要装系统级组件(内核扩展、launch daemon、/Applications之外文件)时用,需要单独的 Developer ID Installer 证书;mas/mas-dev:Mac App Store 提交用(electron.build targets 指南)。 - universal binary:
@electron/universal的makeUniversalApp()把 x64 与 arm64 两个.app粘合(lipo),可用mergeASARs: true合并两架构 asar 以减小体积,singleArchFiles(minimatch)声明仅存在于单一架构的文件——"If@electron/universaldetects an architecture-unique file that isn't covered by thesingleArchFilesrule, an error will be thrown"(GitHub README)。未合并时 universal 体积近似两倍,应权衡:分架构包小但下载页需要按 CPU 分流。
Windows:NSIS(默认)/ nsis-web / portable / MSI / MSIX
electron-builder targets 指南的官方口径:NSIS 是默认与多数应用的最佳选择(支持 per-user 免管理员安装;oneClick 默认 true,perMachine 默认 false,differentialPackage 默认 true);nsis-web 适合超大应用——生成小 stub 安装器、安装时下载 payload;portable 免安装;MSI 面向企业 SCCM/Intune/GPO;appx 为 Store 遗留格式,msix 是"modern successor to AppX"但官方标注 beta;squirrel.windows 标注 Legacy (not recommended)。Microsoft Store 路线:上架后由微软重签,"Users will never see a SmartScreen warning for a Store-installed app"(Microsoft Learn)。Electron 官方 windows-store-guide 仍讲的是 electron-windows-store 打 appx 的老流程。
Linux:AppImage / deb / rpm / snap / flatpak
electron-builder 默认构建 AppImage + snap,AppImage 是官方推荐的跨发行版首选:单文件、免安装、免 root,且支持内嵌 blockmap 的差量更新;deb/rpm 覆盖 Debian/Red Hat 系包管理器;snap 走 Snap Store(严格沙箱、需 snapd);flatpak 跨发行版沙箱;pacman(Arch)为 beta。electron-builder 文档给出的对比要点:AppImage 无沙箱、Snap/Flatpak 有;deb/rpm 需要 root 且不跨发行版。Electron 官方另有 snapcraft.md 指南。
8.4 代码签名与公证全流程
macOS:Developer ID + Hardened Runtime + notarization
自 macOS Catalina 起官方分发要求签名 + 公证(Electron 官方 code-signing 文档:先 codesign 再上传 Apple 做 "notarization",通过后 staple 票据)。流水线:
- Apple Developer Program 付费账号 + Developer ID Application 证书(pkg 另需 Developer ID Installer);
- 以 Hardened Runtime(
codesign --options runtime)签名并附带 entitlements——Electron 最低需要com.apple.security.cs.allow-jit与com.apple.security.cs.allow-unsigned-executable-memory(electron-builder notarization 文档); xcrun notarytool submit ... --wait提交公证(altool已于 2023-11-01 被移除,二手来源 Fora Soft 2026 博客确认所有现代管线均用 notarytool——待向 Apple 官方页面核实);xcrun stapler staple钉票据,spctl -a -vv验证。
Forge 配置(osxSign / osxNotarize)示例:
// forge.config.js
module.exports = {
packagerConfig: {
osxSign: { identity: 'Developer ID Application: Acme (TEAMID)' },
osxNotarize: {
tool: 'notarytool',
appleId: process.env.APPLE_ID,
appleIdPassword: process.env.APPLE_APP_SPECIFIC_PASSWORD,
teamId: process.env.APPLE_TEAM_ID,
},
},
};CI 认证推荐 App Store Connect API Key(.p8) 方案:官方文档指出 API key"don't expire and don't require two-factor authentication, making them ideal for CI",而 Apple ID + app-specific password 方式在 CI 上易受 2FA 干扰(electron-builder notarization 文档给出 Option A/B/C 三种认证)。验证环节可用 codesign -dv 检查 flags=0x10000(runtime) 确认 Hardened Runtime 生效、TeamIdentifier 非空、bundle identifier 不是默认的 com.github.Electron(artmann.co 实践)。另注意 app 与 dmg 要"双层级"签名公证——只公证 .app 不公证 .dmg(或相反)都会留下 Gatekeeper 拦截面(sushi.dev 坑清单)。注意官方文档列出的依赖签名的 macOS API:safeStorage、app.setLoginItemSettings()、cookieEncryption fuse、以及 Squirrel.Mac 的 autoUpdater("requires the app to be signed for automatic updates to work at all")。
Windows:证书类型、SmartScreen 与 Azure Artifact Signing
2025-2026 的关键变化,两份官方文档表述存在张力,如实并列:
- Electron 官方文档(electronjs.org code-signing):"since June 2023, Microsoft requires software to be signed with an 'extended validation' certificate… These simpler certificates no longer provide benefits: Windows will treat your app as completely unsigned"。
- Microsoft Learn(SmartScreen reputation for Windows app developers):"EV certificates no longer bypass SmartScreen… EV certificates may matter for enterprise procurement, but they no longer impact SmartScreen behavior. Paying a premium for EV solely to avoid SmartScreen warnings is no longer justified"。
实践结论(ToDesktop 2026 PSA):EV 不再带来即时信誉,OV 与 EV 对 SmartScreen 效果等同;SmartScreen 信誉按文件哈希累积,新版本哈希重新计分;2026-03-26 前后 Azure CA 轮换曾导致大量已签应用触发告警——因此避免在发版临近时轮换签名身份。
Azure Artifact Signing(原 Trusted Signing) 是 Electron 官方文档与 Microsoft Learn 共同推荐的最便宜方案,"gets rid of SmartScreen warnings",但有地域资格限制(Electron Forge 文档:截至 2025-10,仅面向美/加且具 3 年以上可验证经营历史的组织及美/加个人开发者,政策可能变化);Linux/macOS 上可用 jsign 跨平台签名。EV 证书须存于 FIPS 140 Level 2 硬件或云 HSM,因此 CI 场景普遍用云签名(Electron 官方自身用 DigiCert KeyLocker)。生态统一层:@electron/windows-sign 的 windowsSign 配置可跨 Forge、packager、electron-winstaller、electron-wix-msi 复用;electron-builder 有自己的 win.azureSignOptions。
Linux 签名现状
Electron 官方 code-signing 文档只有 macOS 与 Windows 两章,没有 Linux 章节(本调研核对了文档全文)——即官方工具链不提供 Linux 代码签名。现状:AppImage 无内建签名机制,惯例是发布 SHA-256 校验和(细节待核实);Snap 由 Snap Store 审核并签名分发;Flatpak 依托 GPG 签名的 OSTree 仓库与 Flathub(待核实)。Linux 桌面生态整体不依赖签名做安装门禁。
8.5 asar、代码保护与解包风险
机制:官方文档说明 asar 归档的意义是缓解 Windows 长路径问题、加速 require、以及 "conceal your source code from cursory inspection"——注意措辞:只防"随手翻看",不防逆向(electronjs.org asar-archives)。asar 是只读虚拟文件系统;依赖真实路径的系统调用(如 native addon 的部分行为)会触发解包,因此 .node 等文件用 --unpack 留在 app.asar.unpacked 一起分发,反病毒软件有时会被"API 触发的临时解包"行为惊动(同文档)。
解包风险:npx asar extract app.asar out 一条命令即可还原全部 JS 源码;安全研究者还演示过 extract → 修改 → repack → 重算 header hash → 改二进制内嵌哈希的完整篡改链(InfoSec Write-ups)。历史上多个 ASAR integrity 绕过 CVE:CVE-2023-44402(macOS filetype confusion,影响 ≤27.0.0-alpha6)、CVE-2024-46992(Windows,Electron 30/31 beta)、CVE-2025-55305(仅影响同时开启 embeddedAsarIntegrityValidation 与 onlyLoadAppFromAsar 两个 fuse 且攻击者对 resources 目录有写权限的应用;修复于 35.7.5 / 36.8.1 / 37.3.1 / 38.0.0-beta.6,GitLab Advisory Database)。
ASAR Integrity:macOS 自 Electron ≥ 16、Windows 自 ≥ 30 支持;默认关闭,需在构建期开启 EnableEmbeddedAsarIntegrityValidation fuse 并配合 OnlyLoadAppFromAsar,运行时校验 asar header 哈希、不匹配即强制退出(electronjs.org asar-integrity)。electron-builder 通过 electronFuses 配置,Forge 用 @electron-forge/plugin-fuses。MAS 构建官方"recommended as a best practice"。
更强的保护是 V8 bytecode(把入口编译为字节码,源码不再以明文存在于 asar),electron-vite 官方指南给出 "V8 Bytecode + ASAR Integrity" 组合方案,并强调"没有客户端保护是绝对的",核心逻辑仍应放服务端。
8.6 安装包体积优化
- 压缩级别:electron-builder 顶层
compression支持store/normal/maximum,默认normal;官方文档明确 "maximum doesn't lead to noticeable size difference, but increase build time"。 - 裁剪:
filesglob 排除多余文件(带!前缀);electronLanguages只保留所需 locale(默认打包全部 Electron 语言包);native 依赖按平台/架构拆分。 - 按需下载:Windows 大应用用
nsis-web(stub 安装器安装时拉取 payload);应用内资源(模型、素材)首启后下载而非全打进安装包。 - 差量更新(比首装更重要):electron-builder 为 NSIS 产物生成
.blockmap,electron-updater据此做块级差量下载;NSISdifferentialPackage默认true,可选"store-asar"(asar 不压缩、差分更小、安装器更大);AppImage 则把 blockmap 内嵌进二进制。客户端接入只需:
// 应用内(electron-builder + electron-updater)
const { autoUpdater } = require('electron-updater');
autoUpdater.checkForUpdatesAndNotify();
// 差量逻辑由 electron-updater 内部完成:比对新旧 blockmap,
// 仅下载内容变化的块;失败则回退整包下载坑:差量失败会静默回退全量下载(issue #6935 的 "Cannot parse blockmap… fallback to full download");2026-01 的 issue #9498 直接质询三平台差量更新是否被官方稳定支持,被 close as not planned,文档确实薄弱——上线前应自行验证实际下载量。
- 更新 feed 与灰度:electron-builder 构建时会生成更新元数据——"latest.yml (or latest-mac.yml for macOS, or latest-linux.yml for Linux) will be generated and uploaded for all providers",客户端侧的
app-update.yml也随构建自动生成;官方文档另确认 "Download progress and staged rollouts supported on all platforms",即三平台均支持下载进度与灰度放量,这对国内大用户量分发(先放量 1% 观察)很关键(官方 auto-update 文档)。 - macOS universal:
mergeASARs合并双架构 asar,避免体积×2(见 8.3)。 - 更新 payload 用 zip 而非 dmg(electron-updater 约定)。
8.7 国内网络环境的特殊考虑
- 构建期:
@electron/get支持镜像:环境变量ELECTRON_MIRROR(及ELECTRON_NIGHTLY_MIRROR、ELECTRON_CUSTOM_DIR等)或 APImirrorOptions.mirror(GitHub README 实测核对);阿里 npmmirror 提供https://npmmirror.com/mirrors/electron/与 electron-builder 二进制镜像,国内项目惯例是在.npmrc中固定:
# .npmrc —— 国内构建环境常见配置(实践惯例,二进制镜像本身由 npmmirror 官方维护)
electron_mirror=https://npmmirror.com/mirrors/electron/
electron_builder_binaries_mirror=https://npmmirror.com/mirrors/electron-builder-binaries/注意 electron-builder v27 起配置键由 electronDownload 改为 electronGet,镜像参数移入 mirrorOptions.mirror(官方 Configuration 文档);旧文档常见的 ELECTRON_MIRROR 环境变量写法对 @electron/get 5.x 依然有效。此外打包依赖(app-builder 二进制、winCodeSign、nsis 等)默认从 GitHub 拉取,同样受网络影响,镜像变量需在 CI 与本地同时配置。
- 分发期:GitHub Releases 直链在国内不稳,更新 feed 建议用
provider: generic指向国内 CDN/OSS;blockmap 差量可显著降低带宽成本(但见 8.6 的回退坑)。国产头部 Electron 应用(钉钉、QQ NT、飞书等)普遍自建更新服务,公开工程资料有限——待核实。
8.8 常见坑与反模式(清单)
- 只在 CI 有证书的机器上才能构建:应像 artmann.co 指南那样以
APPLE_TEAM_ID等环境变量做门控,无证书时跳过签名,保证贡献者本地可构建。 .p12导出时漏掉私钥,CI 报错难定位;.p8只能下载一次。- 导出
.p12未含私钥、签名 identity 与证书 Common Name 不匹配、忘记--timestamp:公证会被拒(sushi.dev 常见坑清单)。 - 用 Apple Development 证书而非 Developer ID Application 分发。
- Hardened Runtime 首次签名后 native module 崩溃未做冒烟测试——签名后的构建是这些代码路径第一次真实运行(artmann.co)。
- 开 ASAR integrity 却不开
OnlyLoadAppFromAsar(可经 app 目录绕过),或 Electron 版本落后于 CVE-2025-55305 修复线。 - 以为 asar 能保护源码/密钥——必须 V8 bytecode + 服务端逻辑。
- 为「过 SmartScreen」单独买昂贵 EV 证书(2026 年已无此收益,Microsoft Learn),或发版前轮换签名证书。
- Electron ≥ 44 还在为 win-ia32 / linux-armv7l 出包(官方构建已停发)。
- 差量更新「配了就生效」——必须实测下载流量,blockmap 解析失败会静默回退全量。
- 公证通过却忘记
xcrun stapler staple:票据不落地,Gatekeeper 离线首启仍可能拦(sushi.dev:staple 的意义是"so Gatekeeper can check it offline")。发布脚本应把公证、钉票据、验证三步串成一条不可跳过的流水线。
参考来源
- Electron 官方:Distributing Apps With Electron Forge — https://electronjs.org/docs/latest/tutorial/forge-overview
- Electron 官方:Code Signing — https://electronjs.org/docs/latest/tutorial/code-signing
- Electron 官方:ASAR Archives — https://electronjs.org/docs/latest/tutorial/asar-archives
- Electron 官方:ASAR Integrity — https://electronjs.org/docs/latest/tutorial/asar-integrity
- Electron 官方:Snapcraft Guide — https://electronjs.org/docs/latest/tutorial/snapcraft
- Electron 官方:Windows Store Guide — https://electronjs.org/docs/latest/tutorial/windows-store-guide
- @electron/packager README(架构停发与 Node 版本要求)— https://github.com/electron/packager
- @electron/universal README(universal 构建与 mergeASARs)— https://github.com/electron/universal
- @electron/get README(ELECTRON_MIRROR 等)— https://github.com/electron/get
- Electron Forge:Why Electron Forge — https://www.electronforge.io/core-concepts/why-electron-forge
- Electron Forge:Signing a Windows app — https://www.electronforge.io/guides/code-signing/code-signing-windows
- electron-builder:Target Selection Guide — https://www.electron.build/docs/targets
- electron-builder:NSIS 配置 — https://www.electron.build/docs/nsis
- electron-builder:Configuration(compression/electronGet)— https://www.electron.build/docs/configuration
- electron-builder:macOS Notarization — https://www.electron.build/docs/features/code-signing/notarization
- electron-builder:Electron Forge Integration — https://www.electron.build/docs/features/electron-forge
- electron-builder:AppImage(内嵌 blockmap)— https://www.electron.build/docs/appimage
- electron-builder Releases(26.17.0 / 27.0.0-alpha.9)— https://github.com/electron-userland/electron-builder/releases
- Issue #6935(差量回退全量)— https://github.com/electron-userland/electron-builder/issues/6935
- Issue #9498(差量更新支持质疑)— https://github.com/electron-userland/electron-builder/issues/9498
- Microsoft Learn:SmartScreen reputation for Windows app developers — https://learn.microsoft.com/en-us/windows/apps/package-and-deploy/smartscreen-reputation
- GitLab Advisory:CVE-2025-55305 — https://advisories.gitlab.com/npm/electron/CVE-2025-55305
- ToDesktop:EV Certs PSA(2026)— https://www.todesktop.com/blog/posts/windows-apps-psa-ev-certs-do-not-grant-immediate-reputation-anymore
- Fora Soft:How to Notarize & Publish an Electron App on macOS (2026)— https://www.forasoft.com/blog/article/the-pain-of-publishing-electron-apps-on-macos-303
- artmann.co:Signing, Notarizing, and Publishing — https://www.artmann.co/articles/signing-notarizing-and-publishing-an-electron-app-for-mac-os
- sushi.dev:Notarization of Mac Apps — https://sushi.dev/en/blog/notarization-of-mac-apps
- electron-vite:Source Code Protection(V8 Bytecode)— https://electron-vite.org/guide/source-code-protection
- InfoSec Write-ups:Electron ASAR Integrity Bypass — https://infosecwriteups.com/electron-js-asar-integrity-bypass-431ac4269ed5
- noh.am:Unpacking and repacking Electron apps(CVE 史)— https://noh.am/en/posts/unpacking-and-repacking-electron-apps
- 版本号实测(2026-10-04,
npm view):electron 44.5.1 / electron-builder 26.15.3(latest)、26.17.0(v26)、27.0.0-alpha.9(next)/ @electron-forge/cli 8.0.1 / electron-updater 6.8.9 / @electron/notarize 3.1.1 / @electron/get 5.1.0
最后更新于