一、为什么用 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
| { "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
| 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 即自动构建三平台安装包并发布。
常见坑
files 配置漏文件导致白屏:渲染进程页面和 preload 没打进包,运行一片白,检查 files 列表;
- NSIS 安装后无法运行:多数是杀毒软件误报或签名问题,先本地
electron . 验证主进程正常;
- macOS 提示”已损坏”:没签名或签名被 Gatekeeper 拦截,
xattr -cr 只能本地临时解决,正式分发必须签名 + 公证;
- 自动更新一直失败:先确认
latest*.yml 和安装包在同目录、URL 可访问、版本号比本机高。
总结
打包发布的完整链路:electron-builder 配置 → 图标 → 签名(win/mac)→ 产物 + latest.yml 上传 → electron-updater 自动更新 → CI 打 tag 自动化。前两次手工跑通后,后面交给 CI 就好。