第 8 章:应用打包与跨平台发布
开发完成后,你需要将应用打包成可执行文件,分发给用户。本章将学习使用 electron-builder 进行应用打包, 配置 Windows 和 macOS 的打包选项,以及代码签名和发布流程。
8.1 electron-builder 简介
electron-builder 是目前最流行的 Electron 应用打包工具,它可以将你的应用打包成 Windows 的 .exe/.msi、
macOS 的 .dmg/.pkg、Linux 的 .AppImage/.deb 等格式。
把 electron-builder 想象成 Webpack/Vite 的打包阶段,只不过它打包的不是网页,而是完整的桌面应用。 配置方式也很相似——通过配置文件定义入口、输出、插件等。
安装 electron-builder
# 作为开发依赖安装
npm install electron-builder --save-dev
# 或者使用 yarn
yarn add electron-builder --dev
8.2 配置 electron-builder
electron-builder 支持多种配置方式:package.json 中的 build 字段、独立的 electron-builder.yml 文件、
或通过命令行参数。推荐使用独立的 YAML 配置文件,更清晰易维护。
基础配置(electron-builder.yml)
# 应用基本信息
appId: com.yourcompany.yourapp
productName: "RPA Desktop Assistant"
copyright: "Copyright © 2024 Your Company"
# 打包输出目录
directories:
output: dist
buildResources: build
# 文件包含规则
files:
- "out/**/*"
- "node_modules/**/*"
- "package.json"
- "!node_modules/.cache"
- "!**/*.map"
# 额外资源(不打包到 asar 中)
extraResources:
- from: "assets/"
to: "assets"
- from: "templates/"
to: "templates"
# ASAR 配置
asar: true
asarUnpack:
- "node_modules/sharp/**/*"
- "node_modules/@nut-tree/**/*"
# Windows 配置
win:
target:
- target: nsis
arch:
- x64
- ia32
- target: portable
arch:
- x64
icon: build/icon.ico
publisherName: "Your Company"
verifyUpdateCodeSignature: false
# macOS 配置
mac:
target:
- target: dmg
arch:
- x64
- arm64
- target: zip
arch:
- x64
- arm64
icon: build/icon.icns
category: public.app-category.productivity
hardenedRuntime: true
gatekeeperAssess: false
# Linux 配置
linux:
target:
- AppImage
- deb
icon: build/icons
category: Office
# NSIS 安装程序配置(Windows)
nsis:
oneClick: false
allowToChangeInstallationDirectory: true
createDesktopShortcut: always
createStartMenuShortcut: true
shortcutName: "RPA Assistant"
uninstallDisplayName: "RPA Desktop Assistant"
license: "LICENSE.txt"
artifactName: "${productName}-Setup-${version}.${ext}"
# DMG 配置(macOS)
dmg:
sign: false
contents:
- x: 130
y: 220
- x: 410
y: 220
type: link
path: "/Applications"
package.json 脚本配置
{
"name": "rpa-desktop-assistant",
"version": "1.0.0",
"main": "out/main/index.js",
"scripts": {
"dev": "electron-vite dev",
"build": "electron-vite build",
"preview": "electron-vite preview",
"pack": "electron-builder --dir",
"dist": "electron-builder",
"dist:win": "electron-builder --win",
"dist:mac": "electron-builder --mac",
"dist:linux": "electron-builder --linux",
"postinstall": "electron-builder install-app-deps"
},
"build": {
"extends": "./electron-builder.yml"
}
}
8.3 Windows 打包详解
Windows 是最常用的桌面平台,electron-builder 支持多种 Windows 安装包格式。
| 格式 | 扩展名 | 特点 | 适用场景 |
|---|---|---|---|
| NSIS | .exe | 标准安装程序,支持自定义向导 | 大多数场景 |
| Portable | .exe | 免安装,直接运行 | U盘携带、快速试用 |
| MSI | .msi | 企业部署、组策略安装 | 企业环境 |
| 7z/zip | .7z/.zip | 压缩包,无安装向导 | 高级用户 |
Windows 图标配置
# 准备图标文件
# Windows 图标:256x256 像素的 .ico 文件
# 可以使用在线工具将 PNG 转换为 ICO
# 推荐工具:https://convertio.co/zh/png-ico/
# 图标文件路径(在 electron-builder.yml 中配置)
# win.icon: build/icon.ico
# 多尺寸图标(推荐包含 16x16, 32x32, 48x48, 256x256)
# 可以使用 icotools 或 Resource Hacker 创建
Windows 代码签名
未签名的 Windows 应用会显示"Windows 已保护你的电脑"警告,影响用户体验。 代码签名需要购买证书(约 ¥1000-3000/年)。
# electron-builder.yml - 代码签名配置
win:
certificateFile: "build/certificate.p12"
certificatePassword: "your-password"
# 或者使用环境变量
# certificatePassword: ${env.CERT_PASSWORD}
# 环境变量方式(更安全)
# 在 CI/CD 中设置环境变量
# WIN_CSC_LINK: base64 编码的证书
# WIN_CSC_KEY_PASSWORD: 证书密码
- Certum 开源开发者证书:约 €69/年,验证身份较简单
- Let's Encrypt 不适用:不支持代码签名
- 测试阶段:可以先不签名,正式发布前再购买证书
8.4 macOS 打包详解
macOS 打包相对复杂,需要处理代码签名、公证(Notarization)等流程。
macOS 图标配置
# macOS 图标需要 .icns 格式
# 1. 准备 1024x1024 的 PNG 图标
# 2. 使用 iconutil 或在线工具转换为 .icns
# 使用 iconutil(macOS 自带)
mkdir MyIcon.iconset
sips -z 16 16 icon.png --out MyIcon.iconset/icon_16x16.png
sips -z 32 32 icon.png --out MyIcon.iconset/icon_16x16@2x.png
sips -z 32 32 icon.png --out MyIcon.iconset/icon_32x32.png
sips -z 64 64 icon.png --out MyIcon.iconset/icon_32x32@2x.png
sips -z 128 128 icon.png --out MyIcon.iconset/icon_128x128.png
sips -z 256 256 icon.png --out MyIcon.iconset/icon_128x128@2x.png
sips -z 256 256 icon.png --out MyIcon.iconset/icon_256x256.png
sips -z 512 512 icon.png --out MyIcon.iconset/icon_256x256@2x.png
sips -z 512 512 icon.png --out MyIcon.iconset/icon_512x512.png
sips -z 1024 1024 icon.png --out MyIcon.iconset/icon_512x512@2x.png
iconutil -c icns MyIcon.iconset -o build/icon.icns
rm -rf MyIcon.iconset
macOS 代码签名与公证
macOS 10.15+ 要求所有分发的应用必须经过公证(Notarization),否则无法运行。 这需要 Apple Developer 账号(¥688/年)。
# electron-builder.yml - macOS 签名配置
mac:
icon: build/icon.icns
category: public.app-category.productivity
# 启用强化运行时(Notarization 必需)
hardenedRuntime: true
gatekeeperAssess: false
# 权限声明
entitlements: build/entitlements.mac.plist
entitlementsInherit: build/entitlements.mac.plist
# 公证配置(使用 notarize-cli 或 electron-notarize)
# 需要在环境变量中设置 Apple ID 和 App 专用密码
# APPLE_ID: your-apple-id@example.com
# APPLE_APP_SPECIFIC_PASSWORD: xxxx-xxxx-xxxx-xxxx
# APPLE_TEAM_ID: XXXXXXXXXX
com.apple.security.cs.allow-jit
com.apple.security.cs.allow-dyld-environment-variables
com.apple.security.cs.disable-library-validation
com.apple.security.get-task-allow
com.apple.security.files.user-selected.read-write
com.apple.security.files.downloads.read-write
如果你使用 Apple Silicon Mac 开发,打包的 x64 版本需要在 Intel Mac 上测试。
建议同时构建 x64 和 arm64 两个版本,或使用 universal 二进制(体积较大)。
8.5 资源文件管理
应用中的静态资源(图标、字体、模板文件等)需要正确配置才能在打包后正常访问。
资源文件路径处理
const path = require('path');
const { app } = require('electron');
// 判断是否为打包后的应用
const isPackaged = app.isPackaged;
// 获取资源路径的辅助函数
function getResourcePath(relativePath) {
if (isPackaged) {
// 打包后:资源在 app.asar 或 app.getAppPath() 中
return path.join(process.resourcesPath, relativePath);
} else {
// 开发环境:资源在项目根目录
return path.join(__dirname, '..', relativePath);
}
}
// 使用示例
const iconPath = getResourcePath('assets/icon.png');
const templatePath = getResourcePath('templates/report.html');
// 在 Vue 组件中访问静态资源
// 开发环境:直接引用 public 目录下的文件
// 生产环境:使用 app:// 协议或 file:// 协议
extraResources 配置
某些文件(如可执行程序、动态库)不能打包到 asar 中,需要放在 extraResources 中:
extraResources:
# 整个目录
- from: "assets/"
to: "assets"
filter:
- "**/*"
# 单个文件
- from: "bin/ffmpeg"
to: "bin/ffmpeg"
# 根据平台选择不同文件
- from: "bin/win/"
to: "bin"
filter:
- "**/*"
# 排除某些文件
- from: "templates/"
to: "templates"
filter:
- "**/*.html"
- "**/*.css"
- "!**/*.tmp"
8.6 打包命令与 CI/CD
配置好打包脚本后,可以通过命令行或 CI/CD 流水线自动构建和发布应用。
常用打包命令
# 打包当前平台
npm run dist
# 仅打包 Windows
npm run dist:win
# 仅打包 macOS(需要在 Mac 上执行)
npm run dist:mac
# 仅打包 Linux
npm run dist:linux
# 生成不打包的安装目录(用于调试)
npm run pack
# 指定架构打包
npx electron-builder --win --x64
npx electron-builder --mac --arm64
npx electron-builder --win --ia32
GitHub Actions 自动打包
# .github/workflows/build.yml
name: Build and Release
on:
push:
tags:
- 'v*'
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: 18
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build application
run: npm run build
- name: Build and release
uses: samuelmeuli/action-electron-builder@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
release: ${{ startsWith(github.ref, 'refs/tags/v') }}
env:
# macOS 签名(如果需要)
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
# Windows 签名(如果需要)
WIN_CSC_LINK: ${{ secrets.WIN_CERTIFICATE }}
WIN_CSC_KEY_PASSWORD: ${{ secrets.WIN_CERT_PASSWORD }}
8.7 发布到 GitHub Releases
electron-builder 可以自动将打包结果上传到 GitHub Releases,配合自动更新功能实现应用分发。
# electron-builder.yml - 发布配置
publish:
provider: github
owner: your-username
repo: your-repo-name
releaseType: release # 或 draft(草稿)
# 私有仓库需要 token
# token: ${env.GH_TOKEN}
# 或者在 package.json 中配置
"build": {
"publish": {
"provider": "github",
"releaseType": "release"
}
}
- 版本号管理:使用语义化版本(semver),如 1.2.3
- 构建前清理:确保每次构建都是干净的,删除旧的构建产物
- 测试安装包:在干净的虚拟机中测试安装和卸载流程
- 文件大小优化:排除不必要的依赖和文件,使用 asar 压缩
- 多架构支持:同时提供 x64 和 arm64 版本(macOS)