一、为什么用 electron-builder

Electron 打包方案里,electron-builder 是最主流的:支持 Windows/macOS/Linux 三平台,自动处理安装包(NSIS/DMG/deb)、图标、依赖收集,还内置了自动更新能力。

二、基础配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// package.json
{
"name": "my-desktop-app",
"version": "1.2.0",
"main": "main.js",
"scripts": {
"dist": "electron-builder",
"dist:win": "electron-builder --win",
"dist:mac": "electron-builder --mac",
"dist:linux": "electron-builder --linux"
},
"build": {
"appId": "com.example.mydesktopapp",
"productName": "MyDesktopApp",
"directories": {
"output": "dist"
},
"files": [
"main.js",
"preload.js",
"renderer/**/*"
],
"win": {
"target": ["nsis"],
"icon": "build/icon.ico"
},
"mac": {
"target": ["dmg"],
"icon": "build/icon.icns",
"category": "public.app-category.utilities"
},
"linux": {
"target": ["AppImage", "deb"],
"icon": "build/icon.png"
},
"nsis": {
"oneClick": false,
"allowToChangeInstallationDirectory": true,
"createDesktopShortcut": true
}
}
}

三、图标要求

  • Windows:icon.ico(256x256 起步,多尺寸)
  • macOS:icon.icns(或提供 512x512 png 让工具自动生成)
  • Linux:icon.png(512x512)

没有现成图标时,可以用 electron-icon-builder 从一张 1024x1024 png 生成全平台图标:

1
npx electron-icon-builder --input=./icon.png --output=./build

不配图标的后果:打包能过,但应用会显示默认 Electron 图标,上不了架、观感很差。

四、代码签名(发布必备)

未签名应用在 Windows 会弹 SmartScreen 警告,macOS 会被 Gatekeeper 拦截(”无法验证开发者”)。

Windows 签名:需要代码签名证书(OV/EV 证书),在 CI 里配置:

1
2
3
win:
certificateFile: cert.pfx
certificatePassword: ${CSC_KEY_PASSWORD}

macOS 签名 + 公证(notarization):需要 Apple Developer 证书,electron-builder 支持环境变量配置:

1
CSC_LINK=/path/to/cert.p12 CSC_KEY_PASSWORD=xxx npm run dist:mac

macOS 建议开公证(notarize: true),否则用户首次打开会被系统拦。

五、自动更新:electron-updater

安装:

1
npm install electron-updater

生成更新元数据:electron-builder 打包时默认生成 latest.yml(win)/ latest-mac.yml(mac),里面有版本号和安装包 hash——自动更新靠的就是这个文件。

主进程接入(main.js):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const { autoUpdater } = require('electron-updater')

// 配置更新源:你的静态服务器地址
autoUpdater.setFeedURL({
provider: 'generic',
url: 'https://download.example.com/myapp/'
})

// 检查更新(建议启动后延迟几秒再查,别拖慢首屏)
setTimeout(() => {
autoUpdater.checkForUpdates()
}, 5000)

autoUpdater.on('update-available', () => {
// 提示用户有新版本
dialog.showMessageBox({ message: '发现新版本,正在后台下载...' })
})

autoUpdater.on('update-downloaded', () => {
dialog.showMessageBox({
message: '更新已下载,重启安装?',
buttons: ['立即重启', '稍后']
}).then((res) => {
if (res.response === 0) autoUpdater.quitAndInstall()
})
})

autoUpdater.on('error', (err) => {
console.error('自动更新失败:', err)
})

发版流程:开发完 → npm run dist → 把新版本安装包 + latest*.yml 上传到更新服务器 → 用户下次启动自动收到更新。

六、CI 自动化:GitHub Actions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# .github/workflows/release.yml
name: Build & Release

on:
push:
tags: ["v*"]

jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [windows-latest, macos-latest, ubuntu-latest]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm run dist
env:
CSC_LINK: ${{ secrets.CSC_LINK }}
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
- uses: softprops/action-gh-release@v2
with:
files: |
dist/*.exe
dist/*.dmg
dist/*.AppImage
dist/latest*.yml

打 tag 即自动构建三平台安装包并发布。

常见坑

  1. files 配置漏文件导致白屏:渲染进程页面和 preload 没打进包,运行一片白,检查 files 列表;
  2. NSIS 安装后无法运行:多数是杀毒软件误报或签名问题,先本地 electron . 验证主进程正常;
  3. macOS 提示”已损坏”:没签名或签名被 Gatekeeper 拦截,xattr -cr 只能本地临时解决,正式分发必须签名 + 公证;
  4. 自动更新一直失败:先确认 latest*.yml 和安装包在同目录、URL 可访问、版本号比本机高。

总结

打包发布的完整链路:electron-builder 配置 → 图标 → 签名(win/mac)→ 产物 + latest.yml 上传 → electron-updater 自动更新 → CI 打 tag 自动化。前两次手工跑通后,后面交给 CI 就好。