打包与发布
打包与发布 📦
开发完成后,需要把 Electron 应用打包成可分发的安装包。本章我们学习使用 electron-builder(electron-vite 脚手架默认集成)进行打包与发布。
electron-builder 简介 💎
electron-builder 是 Electron 生态最流行的打包工具,支持:
- 多平台打包:Windows、macOS、Linux
- 多种安装包格式:exe、msi、dmg、pkg、AppImage、deb、rpm、snap
- 自动签名(Windows / macOS)
- 自动更新
- 多语言安装包
- 资源压缩
electron-vite 脚手架的打包配置 💎
使用 pnpm create electron-vite@latest 创建的项目,默认已经集成了 electron-builder,并生成 electron-builder.yml 配置文件。
默认配置 👻
# electron-builder.yml
appId: com.electron.my-app
productName: My App
directories:
buildResources: build
output: dist/${version}
files:
- "!**/.vscode/*"
- "!src/*"
- "!electron.vite.config.{js,ts,mjs,cjs}"
- "!{tsconfig.json,tsconfig.node.json,tsconfig.web.json}"
- "!{.eslintignore,.eslintrc.cjs,.prettierignore,.prettierrc.yaml,dev-app-update.yml,CHANGELOG.md,README.md}"
- "!.env.d.ts"
- "!.env.*"
- "!{*.iml}"
asar: true
win:
executableName: MyApp
nsis:
artifactName: ${productName}-${version}-Setup.${ext}
shortcutName: ${productName}
uninstallDisplayName: ${productName}
createDesktopShortcut: always
mac:
category: public.app-category.developer-tools
target:
- target: dmg
arch:
- x64
- arm64
artifactName: ${productName}-${version}-${arch}.${ext}
linux:
target:
- AppImage
- snap
artifactName: ${productName}-${version}.${ext}
publish: null常用打包命令 👻
# 完整打包(构建 + 制作安装包)
pnpm build:win # Windows:生成 .exe / .nsis 安装包
pnpm build:mac # macOS:生成 .dmg 安装包
pnpm build:linux # Linux:生成 .AppImage / .deb
pnpm build:unpack # 仅打包,不制作安装包
# 在 macOS 上交叉打包 Windows(需要 wine)
pnpm build:win --x64
# 多架构打包(macOS)
pnpm build:mac --arm64
pnpm build:mac --x64electron-vite 提供的脚本
pnpm dev:开发模式pnpm build:构建源码(不打包成安装包)pnpm build:win/build:mac/build:linux:构建并打包成安装包pnpm build:unpack:只构建,不打包pnpm typecheck:类型检查
完善打包配置 💎
下面是一个生产级的 electron-builder.yml 配置:
# 应用元信息
appId: com.yourcompany.yourapp
productName: 你的应用名
copyright: Copyright © 2026 你的公司
# 输出目录
directories:
buildResources: build # 打包资源目录(图标、安装包背景等)
output: release/${version} # 产物输出目录
# 包含的文件
files:
- "!**/.vscode/*"
- "!src/*"
- "!electron.vite.config.*"
- "!{tsconfig*.json}"
- "!.eslint*"
- "!.prettier*"
- "!dev-app-update.yml"
- "!CHANGELOG.md"
- "!README.md"
- "!.env*"
- "!**/*.{iml,md}"
# 不打包进 asar 的文件(必须保留原样)
asarUnpack:
- "resources/**"
# 启用 asar 压缩
asar: true
# 协议
protocols:
- name: 你的应用协议
schemes:
- yourapp
# Windows 配置
win:
# 图标(必须是 .ico 格式)
icon: build/icon.ico
# 可执行文件名
executableName: YourApp
# 目标格式
target:
- target: nsis
arch:
- x64
- ia32
# 代码签名
certificateFile: build/cert.pfx
certificatePassword: ${env.CSC_KEY_PASSWORD}
# 签名算法
signingHashAlgorithms:
- sha256
publisherName: 你的公司名
# Windows NSIS 安装包配置
nsis:
oneClick: false # 是否一键安装
perMachine: false # 是否按机器安装(默认按用户)
allowElevation: true # 允许请求管理员权限
allowToChangeInstallationDirectory: true # 允许选择安装目录
createDesktopShortcut: always # 创建桌面快捷方式
createStartMenuShortcut: true # 创建开始菜单快捷方式
shortcutName: 你的应用名
artifactName: ${productName}-${version}-Setup.${ext}
deleteAppDataOnUninstall: false # 卸载时是否删除数据
# macOS 配置
mac:
category: public.app-category.developer-tools
icon: build/icon.icns
target:
- target: dmg
arch:
- x64
- arm64
- target: zip
arch:
- x64
- arm64
artifactName: ${productName}-${version}-${arch}.${ext}
hardenedRuntime: true
gatekeeperAssess: false
identity: ${env.APPLE_IDENTITY}
notarize: true
notarizeTeamId: ${env.APPLE_TEAM_ID}
entitlements: build/entitlements.mac.plist
entitlementsInherit: build/entitlements.mac.plist
# Linux 配置
linux:
icon: build/icon.png
target:
- target: AppImage
arch:
- x64
- target: deb
arch:
- x64
category: Development
vendor: 你的公司名
artifactName: ${productName}-${version}.${ext}
# 自动更新配置
publish:
provider: generic
url: https://update.yourcompany.com/yourapp
channel: latest应用图标 💎
应用图标是打包前必须准备的资源。electron-builder 会在打包时自动使用 buildResources 目录下的图标文件。
图标要求 👻
| 平台 | 文件格式 | 最小尺寸 | 推荐尺寸 |
|---|---|---|---|
| Windows | .ico | 256x256 | 256x256(含多尺寸) |
| macOS | .icns | 512x512 | 1024x1024 |
| Linux | .png | 512x512 | 1024x1024 |
准备图标 👻
# 项目根目录下的 build 目录
build/
├── icon.ico # Windows 图标
├── icon.icns # macOS 图标
├── icon.png # Linux 图标
├── installerIcon.ico # 安装包图标
└── entitlements.mac.plist # macOS 权限配置可以使用以下工具从 PNG 自动生成各平台图标:
- electron-icon-builder(推荐)
# 安装
pnpm add -D electron-icon-builder
# 准备一张 1024x1024 的 PNG,命名为 icon.png 放在 build 目录
# 然后执行:
pnpm electron-icon-builder --input=build/icon.png --output=build会自动生成:
build/
├── icon.icns
├── icon.ico
├── icon.png
├── icons/
│ ├── 16x16.png
│ ├── 32x32.png
│ ├── 48x48.png
│ ├── 64x64.png
│ ├── 128x128.png
│ ├── 256x256.png
│ └── 512x512.pngmacOS 代码签名与公证 💎
macOS 应用必须经过代码签名 + 公证才能在其它电脑正常打开(否则会提示"无法验证开发者")。
申请开发者证书 👻
- 登录 Apple Developer
- 进入 "Certificates, Identifiers & Profiles"
- 创建 "Developer ID Application" 证书
- 下载并安装到钥匙串
准备 entitlements 👻
<!-- build/entitlements.mac.plist -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- 网络客户端 -->
<key>com.apple.security.network.client</key>
<true/>
<!-- 网络服务端 -->
<key>com.apple.security.network.server</key>
<true/>
<!-- 读写用户选择的文件 -->
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<!-- 摄像头 -->
<key>com.apple.security.device.camera</key>
<true/>
<!-- 麦克风 -->
<key>com.apple.security.device.audio-input</key>
<true/>
<!-- 硬件加速 -->
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
</dict>
</plist>配置环境变量 👻
# macOS
export CSC_LINK=/path/to/cert.p12
export CSC_KEY_PASSWORD=your-cert-password
export APPLE_ID=your-apple-id@example.com
export APPLE_APP_SPECIFIC_PASSWORD=abcd-efgh-ijkl-mnop
export APPLE_TEAM_ID=YOURTEAMID
# 然后执行
pnpm build:macelectron-builder 会自动完成签名 + 上传公证。
Windows 代码签名 💎
Windows 应用签名后可以避免 SmartScreen 警告。
# 准备代码签名证书(.pfx 格式)
# Windows 上设置环境变量
set CSC_LINK=C:\path\to\cert.pfx
set CSC_KEY_PASSWORD=your-cert-password
# 执行打包
pnpm build:win推荐的证书服务商
- DigiCert
- Sectigo (Comodo)
- GlobalSign
- Certum(价格便宜,个人开发者可选)
减小安装包体积 💎
Electron 应用的安装包通常较大(100MB+),以下是常见的优化手段:
1. 启用 asar 压缩 👻
# electron-builder.yml
asar: trueasar 是一种类似 tar 的归档格式,能有效减小产物体积。
2. 拆分大型依赖 👻
将一些大型依赖(如 electron-updater)放在 dependencies 而不是 devDependencies:
{
"dependencies": {
"electron-updater": "^6.0.0"
}
}3. 排除不必要的语言包 👻
# electron-builder.yml
electronLanguages:
- zh-CN
- en-US
# 排除其它语言包,减小体积约 30MB4. 拆分渲染进程依赖 👻
对于特别大的依赖(如 monaco-editor、echarts),可以放到 CDN 或运行时动态加载。
5. 使用分卷安装包 👻
nsis:
differentialPackage: true # 差分更新自动更新 💎
electron-builder 自带 electron-updater 模块,可以实现增量更新。
主进程代码 👻
// src/main/updater.ts
import { autoUpdater } from 'electron-updater'
import { BrowserWindow } from 'electron'
export function setupAutoUpdater(): void {
// 配置
autoUpdater.autoDownload = false // 不自动下载,提示用户
autoUpdater.autoInstallOnAppQuit = true // 应用退出时自动安装
// 检查更新
autoUpdater.on('checking-for-update', () => {
console.log('正在检查更新...')
})
autoUpdater.on('update-available', (info) => {
console.log('发现新版本:', info.version)
// 通知渲染进程弹出更新提示
BrowserWindow.getAllWindows().forEach((win) => {
win.webContents.send('updater:update-available', {
version: info.version,
releaseNotes: info.releaseNotes,
})
})
})
autoUpdater.on('update-not-available', () => {
console.log('当前已是最新版本')
})
autoUpdater.on('download-progress', (progress) => {
BrowserWindow.getAllWindows().forEach((win) => {
win.webContents.send('updater:download-progress', {
percent: progress.percent,
transferred: progress.transferred,
total: progress.total,
})
})
})
autoUpdater.on('update-downloaded', (info) => {
BrowserWindow.getAllWindows().forEach((win) => {
win.webContents.send('updater:update-downloaded', {
version: info.version,
})
})
})
autoUpdater.on('error', (err) => {
console.error('更新失败:', err)
})
// 启动时检查更新
autoUpdater.checkForUpdates()
}渲染进程(Vue) 👻
<template>
<div v-if="updateInfo" class="update-dialog">
<p>发现新版本:{{ updateInfo.version }}</p>
<button v-if="!downloading" @click="downloadUpdate">立即更新</button>
<div v-else class="progress">
<div class="bar" :style="{ width: progress + '%' }"></div>
<span>{{ Math.round(progress) }}%</span>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
const updateInfo = ref<any>(null)
const downloading = ref(false)
const progress = ref(0)
onMounted(() => {
;(window as any).updaterApi.onUpdateAvailable((info: any) => {
updateInfo.value = info
})
;(window as any).updaterApi.onDownloadProgress((p: any) => {
progress.value = p.percent
})
;(window as any).updaterApi.onUpdateDownloaded(() => {
if (confirm('新版本已下载完成,是否立即重启应用?')) {
;(window as any).updaterApi.installUpdate()
}
})
})
const downloadUpdate = () => {
downloading.value = true
;(window as any).updaterApi.downloadUpdate()
}
</script>配置更新服务器 👻
# electron-builder.yml
publish:
provider: generic
url: https://update.yourcompany.com/yourapp
channel: latest将打包后的 latest.yml(Windows)、latest-mac.yml(macOS)、latest-linux.yml(Linux)三个文件 + 完整的安装包上传到服务器即可。
常见问题 💎
打包后白屏 👻
通常是文件未正确打包进 asar,可以:
# 排除特定文件
asarUnpack:
- "**/*.node"
- "**/*.dll"Windows 安装包被杀毒软件误报 👻
未签名的应用容易被误报。解决方案:
- 申请 EV 代码签名证书
- 提交到杀毒软件厂商加入白名单
- 使用更知名的分发渠道
macOS 提示"无法打开,因为它来自身份不明的开发者" 👻
需要:
- 代码签名
- 公证(Notarization)
- 或用户在"系统设置 → 隐私与安全性"手动允许
自动更新失败 👻
检查:
- 更新服务器地址是否正确
latest.yml文件是否在正确位置- 服务器 HTTPS 证书是否有效
- 应用版本号是否真的低于服务器版本
小结
本章我们学习了 Electron 应用的完整打包与发布流程:
- electron-builder 配置:多平台、图标、签名、自动更新
- 图标资源准备:各平台图标格式
- 代码签名与公证:macOS、Windows
- 体积优化:asar 压缩、语言包裁剪
- 自动更新:electron-updater 集成
至此,Electron 章节的基础知识就告一段落了。后续可根据项目需求继续深入学习:
- 性能优化(启动速度、内存占用)
- 调试技巧(DevTools、Chrome DevTools 协议)
- 与原生模块集成(C++ addons)
- 安全性最佳实践
至此,本章节的学习就到此结束了,如有疑惑,可对接技术客服进行相关咨询。