共计 7242 个字符,预计需要花费 19 分钟才能阅读完成。
提醒:本文最后更新于2025-07-07 14:41,文中所关联的信息可能已发生改变,请知悉!
electron-builder
与 electron-packager
都可以用来将 webapp 通过 Electron 应用打包为桌面客户端然后发布。
这两个工具都支持命令行工具和 JSAPI 方式。在有复杂的多环境构建需求的情况下,通过 JSAPI 定制不同的参数更为方便可控。但是由于参数众多的原因,实现想要的效果需要注意较多的细节,可能会采一些坑才能达到目的。
本文将分别简要介绍使用 electron-builder
与 electron-packager
的 JSAPI 实现打包应用程序的一些实践细节。
1 项目主要目录结构
我们设定项目构建相关的目录结构如下:
├─src web 应用源码目录 | |
├─electron Native 应用构建相关的源码目录 | |
│ ├─resources 各种资源文件 | |
│ └─src Native 逻辑源码目录 | |
├─dist | |
│ ├─electron 构建APP所有需要的资源都需先输出至该目录 | |
│ │ ├─app dist/webapp 的副本,用于打包进 Native App 中的本地应用 | |
│ │ └─resources | |
│ └─webapp web 应用构建输出后的资源目录 | |
示例 DEMO 项目参考:github-user-search-vue
2 使用 electron-packager 打包 Electron 应用
electron-packager
可以简单方便地打包出各种系统环境下未压缩的免安装版本。然后再使用其他工具将这些免安装目录打包成安装程序,即可达到目的。
electron-packager
打包构建的执行需要使用系统管理员权限启动。核心代码示例:
const chalk = require('chalk'); | |
const path = require('path'); | |
const packager = require('electron-packager'); | |
// const buildSrc = require('./build-src'); | |
// const CFG = require('./src/electron.config'); | |
const argv = require('minimist')(process.argv.slice(2)); | |
const startPack = () => { | |
const packEnv = 'test'; // CFG.getPackEnv(argv.env); | |
const resDir = path.join(__dirname, `./resources/res-${packEnv}`); | |
const platform = argv.platform || process.env.PACK_PLATFORM || 'all'; | |
/** | |
* `electron-packager` options | |
* https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options | |
*/ | |
const opts = { | |
// Target 'x64' architecture | |
arch: process.env.PACK_ARCH || 'x64', // 'ia32' | |
// Compress app using 'electron/asar' | |
asar: true, | |
// The source directory | |
dir: path.join(__dirname, '../dist/electron'), | |
// Set electron app icon File extensions are added based on platform | |
icon: path.join(resDir, `app.ico`), | |
// Ignore files that would bloat final build size | |
ignore: /(^\/(src|test|\.[a-z]+|README|yarn|static|dist\/web))|\.gitkeep/, | |
// Save builds to `builds` | |
out: path.join(__dirname, `../release/packager-gus-${packEnv}`), | |
// Overwrite existing builds | |
overwrite: true, | |
electronVersion: '3.0.10', | |
// appVersion: pkg.version, | |
appCopyright: `Copyright(C) ${new Date().getFullYear()} lzwme, Inc. All rights reseved.`, | |
platform, | |
// Windows targets only | |
win32metadata: { | |
CompanyName: 'lzwme', | |
}, | |
/** OS X/Mac App Store targets only */ | |
appBundleId: `com.lzwme.gus-${packEnv}`, | |
osxSign: false, | |
}; | |
console.log(chalk.yellow.bold('Release For Env: '), chalk.bold.green(packEnv)); | |
console.log(chalk.cyan.bold('Release To:'), opts.out, '\n'); | |
return packager(opts).then(appPaths => { | |
console.log(chalk.green.bold('\n Done!')); | |
}).catch(err=> { | |
console.log(err); | |
}); | |
} | |
startPack(); | |
// buildSrc.start().then(() => startPack()); |
在 windows 下的构建结果示例:
2.1 使用 electron-installer-windows 打包为 windows 下的安装程序
electron-packager
构建出来的结果是免安装的目录。我们可以继续使用其他工具将他们分别打包为可安装的应用。
对于 windows 系统,可以采用 electron-installer-windows
,示例如下:
const installer = require('electron-installer-windows'); | |
const options = { | |
src: 'release/packager-gus-test/lzwme-gus-test-win32-x64/', | |
dest: 'release/packager-gus-test/', | |
icon: 'resources/icon.ico', | |
}; | |
console.log('Creating package (this may take a while)'); | |
installer(options) | |
.then(() => console.log(`Successfully created package at ${options.dest}`)) | |
.catch(err => { | |
console.error(err, err.stack); | |
process.exit(1); | |
}); |
命令行打包的方式也比较简单:
.\node_modules\.bin\electron-installer-windows --src release/packager-gus-test/lzwme-gus-test-win32-x64/ --dest release/packager-gus-test/ --icon dist/electron/resources/app.ico
不过这里的执行高概率会报错,重新执行可能会成功,具体原因暂时未知。
2.2 使用 electron-osx-sign 给 macOS 的应用签名
该操作应当在 macOS 系统平台下进行。
const signAsync = require('electron-osx-sign').signAsync; | |
signAsync({ | |
app: 'release/packager-gus-test/lzwme-gus-test-mas-x64/lzwme-gus-test.app', | |
}) | |
.then(function () { | |
console.log('Application signed'); | |
}) | |
.catch(function (err) { | |
console.log(err); | |
}); |
2.3 使用 electron-installer-dmg 打包 mac 下的 dmg 安装包
该操作只能在 macOS 系统平台下进行。
const createDMG = require('electron-installer-dmg'); | |
createDMG({ | |
appPath: 'release/packager-gus-test/lzwme-gus-test-mas-x64/lzwme-gus-test.app', | |
name: 'gus-test', | |
// The title of the produced DMG, which will be shown when mounted. | |
title: 'lzwme-gus-test', | |
overwrite: true, | |
out: 'release/packager-gus-test', | |
icon: 'resources/app.png', | |
iconSize: '', | |
}, function done (err) { | |
if (err) { | |
console.log(err); | |
return; | |
} | |
console.log('done!'); | |
}); |
3 使用 electron-builder 打包 Electron 应用
electron-packager
构建出来的结果是免安装的目录,效果很好,速度很快。但还需借助其它的插件打包为可安装程序包。
相比较而言,electron-builder
可以直接构建输出用于安装的程序包,配置项上也因此更为灵活多样。核心示例代码:
const chalk = require('chalk'); | |
const builder = require('electron-builder'); | |
const Platform = builder.Platform; | |
const path = require('path'); | |
const CFG = require('./src/electron.config'); | |
const buildSrc = require('./build-src'); | |
const argv = require('minimist')(process.argv.slice(2)); | |
const packEnv = CFG.getPackEnv(argv.env); | |
const platform = argv['platform'] || 'all'; | |
const resDir = path.join(__dirname, `./resources/res-${packEnv}`); | |
/** | |
* `electron-builder` options | |
* https://electron.build/configuration/configuration | |
*/ | |
const opts = { | |
appId: `com.lzwme.gus-${packEnv}.app`, | |
icon: path.join(resDir, `app_256x256.png`), | |
productName: `gus-${packEnv}`, | |
artifactName: '${productName}-${platform}-${arch}_${version}.${ext}', | |
electronVersion: '3.0.10', | |
// remoteBuild: false, | |
directories: { | |
app: path.join(__dirname, '../dist/electron'), | |
buildResources: path.join(__dirname, `./resources/res-${packEnv}`), | |
output: path.join(__dirname, `../release/builder-gus-${packEnv}`), | |
}, | |
dmg: { | |
icon: path.join(resDir, `app.icns`), | |
}, | |
linux: { | |
target: ['zip'], | |
icon: path.join(resDir, `app_256x256.png`), | |
}, | |
mac: { | |
target: ['dmg', 'zip', 'pkg'], | |
icon: path.join(resDir, `app.icns`), | |
}, | |
win: { | |
target: ['nsis', '7z'], // , , 'zip', 'msi' | |
icon: path.join(resDir, `app_256x256.ico`), | |
}, | |
nsis: { | |
oneClick: false, | |
perMachine: true, | |
allowToChangeInstallationDirectory: false, | |
installerHeaderIcon: path.join(resDir, `app_256x256.ico`), | |
installerIcon: path.join(resDir, `app_256x256.ico`), | |
// installerHeader: path.join(resDir, `app_256x256.png`), | |
// installerSidebar: path.join(resDir, `app_256x256.png`), | |
// installerHeader: 'installerHeader.bmp', | |
// include: 'windows/installer.nsh', | |
// script: 'windows/installer.nsi', | |
// publish: {} | |
}, | |
// publish: [{ | |
// "provider": "generic", | |
// //类似于autoUpdater.setFeedURL(url)中的url,用于自动更新的文件地址 | |
// "url": "http://www.xxx.com/" | |
// }], | |
afterPack(packer) { | |
console.log('packed!'); | |
}, | |
}; | |
const buildStart = async () => { | |
console.log(chalk.yellow.bold('Release For Env: '), chalk.bold.green(packEnv)); | |
// 开启调试模式 | |
if (argv.debug) { | |
process.env.DEBUG = 'electron-builder'; | |
} | |
if (['win', 'win32', 'all'].includes(platform)) { | |
await builder.build({ | |
targets: Platform.WINDOWS.createTarget(), | |
config: opts, | |
}); | |
} | |
if (['linux', 'all'].includes(platform)) { | |
await builder.build({ | |
targets: Platform.LINUX.createTarget(), | |
config: opts, | |
}); | |
} | |
// 只有在 mac 平台上才构建 mac 版本 | |
if (process.platform === 'darwin' && ['mac', 'all'].includes(platform)) { | |
await builder.build({ | |
targets: Platform.MAC.createTarget(), | |
config: opts, | |
}); | |
} | |
} | |
buildStart(); |
在 windows 下的构建结果示例:
4 常见问题
4.1 electron-builder
安装过程中 electron 等下载失败
主要可能会出现 electron、winCodeSign、nsis、nsis-resources、wix 等资源包因网络缓慢、被 GFW 而导致下载失败。解决方法参考如下:
1 设置 electron
等从淘宝镜像下载。可设置环境变量,或者在项目目录下增加 .npmrc
文件并配置相关配置项,内容参考如下:
ELECTRON_MIRROR=http://npm.taobao.org/mirrors/electron/ | |
ELECTRON_BUILDER_BINARIES_MIRROR=http://npm.taobao.org/mirrors/electron-builder-binaries/ | |
SELENIUM_CDNURL=http://npm.taobao.org/mirrorss/selenium | |
CHROMEDRIVER_CDNURL=https://npm.taobao.org/mirrors/chromedriver | |
SASS_BINARY_SITE=https://npm.taobao.org/mirrors/node-sass/ |
2 nsis
等的下载报错,可根据错误信息中的提示,手动使用迅雷等下载工具下载相关包,然后解压至临时的缓存目录(一般为 C:\Users\<username>\AppData\Local\electron-builder\Cache
)。然后再次重新安装,则会优先从缓存目录获取内容,不再从网络下载。
以 nsis
为例,参考如下图示例:
参考命令报错提示,手动下载相关文件并解压至 目录。
5 相关参考
- https://github.com/electron-userland/electron-packager
- https://github.com/electron-userland/electron-installer-windows
- https://github.com/electron-userland/electron-installer-dmg
- https://github.com/electron-userland/electron-builder
- https://www.electron.build/api/electron-builder