初探 Electron

官方资源

Electron 框架,通过 JavaScript、HTML 和 CSS 来构建跨平台的桌面应用。它通过将 Chromium 和 Node.js 集成到同一个运行时环境中,使开发者能够维护一个单一的代码库,并在 Windows、macOS 和 Linux 上运行。Electron 的设计消除了需要针对每个平台进行原生应用开发的复杂性。

代码挂在 GitHub 仓库上,如果有帮助,记得给仓库点个赞:https://github.com/RexWzh/Electron-demo

类似工具

Tauri 是一个较新的框架,提供了更现代的技术栈和更高的安全性。Electron 由于其历史悠久和强大的社区支持,仍然保持着广泛的使用。以下是对两种工具的简要比较:

  • Electron:

    • 优点: 社区庞大,支持广泛,文档丰富。
    • 缺点: 性能开销较大,应用体积较大。
  • Tauri:

    • 优点: 更小的资源占用,增强的安全性,允许更紧密地与系统原生功能集成。
    • 缺点: 相对较新,社区和资源较少。

快速示例

以下是一个简单的 Electron 应用开发示例,包含创建过程和基础命令。

开发环境准备

系统版本信息:

1
2
3
4
❯ npm -v
6.14.18
❯ node -v
v20.11.0

npm 使用低版本,避免一些卡顿问题。

创建应用

本示例使用 Vue 和 JavaScript:

1
npm create vite@latest electron-demo

electron-create

项目的目录结构如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.
├── index.html
├── package.json
├── public
│   └── vite.svg
├── README.md
├── src
│   ├── App.vue
│   ├── assets
│   │   └── vue.svg
│   ├── components
│   │   └── HelloWorld.vue
│   ├── main.js
│   └── style.css
└── vite.config.js

4 directories, 10 files

最初考虑使用 pnpm 来实践,但由于 pnpm 对 Electron 的支持存在问题,暂时放弃,详情参阅:知乎文章

安装与启动

建议配置 npm 镜像以加速下载过程:

1
2
3
# npm config set registry https://r.cnpmjs.org
npm install
npm run dev

安装 Electron 过程中的下载可能需要较长时间:

1
npm install electron

添加和修改 Electron 配置

这份代码可以参考官网给的 examples

为了确保 Electron 应用能够正确地引用资源文件(如 CSS 和 JavaScript),需要对 vite.config.js 文件进行适当的修改。这包括设置资源的加载路径为相对路径,以预防文件找不到的问题。

修改 vite.config.js 如下:

1
2
3
4
5
6
7
8
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// 配置基本路径为相对路径
export default defineConfig({
base: './', // 确保打包后的资源可以正确加载
plugins: [vue()],
})

接下来,我们需要添加一个 main.js 文件,这个文件是 Electron 应用的入口,负责控制应用生命周期和创建原生浏览器窗口。

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
43
44
// main.js

// 控制应用生命周期和创建原生浏览器窗口的模组
const { app, BrowserWindow } = require('electron')
const path = require('path')

function createWindow () {
// 创建浏览器窗口
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})

// 加载 index.html
mainWindow.loadFile('dist/index.html') // 此处跟electron官网路径不同,需要注意

// 打开开发工具
// mainWindow.webContents.openDevTools()
}

// 这段程序将会在 Electron 结束初始化
// 和创建浏览器窗口的时候调用
// 部分 API 在 ready 事件触发后才能使用。
app.whenReady().then(() => {
createWindow()

app.on('activate', function () {
// 通常在 macOS 上,当点击 dock 中的应用程序图标时,如果没有其他
// 打开的窗口,那么程序会重新创建一个窗口。
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})

// 除了 macOS 外,当所有窗口都被关闭的时候退出程序。 因此,通常对程序和它们在
// 任务栏上的图标来说,应当保持活跃状态,直到用户使用 Cmd + Q 退出。
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})

// 在这个文件中,你可以包含应用程序剩余的所有部分的代码,
// 也可以拆分成几个文件,然后用 require 导入。

添加 preload.js 文件以在渲染进程中安全地使用 Node.js 模块:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// preload.js

// 所有Node.js API都可以在预加载过程中使用。
// 它拥有与Chrome扩展一样的沙盒。
window.addEventListener('DOMContentLoaded', () => {
const replaceText = (selector, text) => {
const element = document.getElementById(selector)
if (element) element.innerText = text
}

for (const dependency of ['chrome', 'node', 'electron']) {
replaceText(`${dependency}-version`, process.versions[dependency])
}
})

最后,更新 package.json 文件以包括新的启动脚本,使 Electron 能够运行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"name": "electron-demo",
"private": true,
"version": "0.0.0",
"main": "main.js", // 新增
//"type": "module", 创建项目自带的这个要删除,否则会有问题
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"electron:serve": "electron ." //新增 electron运行命令
},
"dependencies": {
"electron": "^27.0.0",
"vue": "^3.3.4"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.2.3",
"vite": "^4.4.5"
}
}

打包和运行 Vue 项目

为了部署 Electron 应用,首先需要对 Vue 项目进行打包。这可以通过以下命令实现:

1
npm run build

打包完成后,通过下列命令启动 Electron 应用:

1
npm run electron:serve

应用运行效果如图所示:

Electron Vue App

热更新开发

为了提升开发效率,可以设置热更新,使得在开发过程中对代码的修改能够即时反映在 Electron 应用中。首先需要修改 main.js 文件中的内容加载方式,从加载本地文件改为加载开发服务器地址:

1
mainWindow.loadURL("http://localhost:5173")  // 更改为开发服务器的 URL

为了确保 Electron 能够在 Vite 开发服务器启动后运行,需引入 concurrentlywait-on 两个 npm 包。concurrently 允许同时运行多个命令,而 wait-on 确保 Electron 在服务器可访问后再启动。

首先,安装这两个工具:

1
npm install -D concurrently wait-on

然后,更新 package.json 中的 scripts 部分,添加用于启动开发环境的命令:

1
2
"electron": "wait-on tcp:5173 && electron .",  // 新增,等待端口5173
"electron:serve": "concurrently -k \"npm run dev\" \"npm run electron\"" // 新增,同时运行 Vite 和 Electron

现在,通过执行 npm run electron:serve,Electron 应用将自动启动并加载 Vite 的开发服务器,实现实时的热更新功能。

环境分离和打包配置

在开发和生产环境中运行 Electron 应用通常需要不同的配置。特别是在涉及到资源加载方式时,比如开发环境中可能从本地服务器加载,而生产环境则从文件系统加载打包后的资源。

环境变量设置

为了在不同环境下切换配置,我们使用 NODE_ENV 环境变量来区分生产环境 (production) 和开发环境 (development)。您也可以根据需要配置额外的环境,如 release

首先,我们组织 Electron 相关的文件到一个单独的目录以便管理:

1
2
3
4
# 在项目根目录下操作
mkdir -p electron
mv main.js electron/
mv preload.js electron/

修改 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
const { app, BrowserWindow } = require('electron')
const path = require('path')
const NODE_ENV = process.env.NODE_ENV // 获取环境变量
// const NODE_ENV = 'development' // 判断开发或生产模式(建议写成这种,开发模式就可以用,等即将打包了再把这个变量换成打包模式)

function createWindow () {
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})

// 根据环境变量决定加载的内容
mainWindow.loadURL(
NODE_ENV === 'development'
? 'http://localhost:5173'
: `file://${path.join(__dirname, '../dist/index.html')}`
)

// 在开发环境中自动打开开发者工具
if (NODE_ENV === "development") {
mainWindow.webContents.openDevTools()
}
}

更新 package.json

更新 package.json 来适应新的文件结构,并确保 NODE_ENV 在启动时正确设置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"name": "electron-demo",
"private": true,
"version": "0.0.0",
"main": "electron/main.js", // 更新入口文件路径
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"electron": "wait-on tcp:5173 && electron .",
"electron:serve": "concurrently -k \"npm run dev\" \"npm run electron\""
},
"devDependencies": {
"electron": "^30.0.2",
"vue": "^3.4.21",
"@vitejs/plugin-vue": "^5.0.4",
"concurrently": "^8.2.2",
"vite": "^5.2.0",
"wait-on": "^7.2.0"
}
}

当设置环境变量 const NODE_ENV = 'development' 时,热更新效果:

Electron Hot Reload

应用打包

打包 Electron 应用之前,需确保已经安装了必要的库,以简化环境设置并支持跨平台打包:

  • cross-env: 用于统一不同操作系统之间的环境变量设置。
  • electron-builder: 助力将 Electron 应用打包成可分发的格式。

安装这些工具的命令如下:

1
npm install -D cross-env electron-builder

打包配置

接下来,在 package.json 中配置打包相关的参数,以确保应用按预期构建。

scripts 部分,添加用于一键打包的命令:

1
"electron:build": "vite build && electron-builder"

针对打包过程的详细配置如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
"build": {
"appId": "com.dweb.electron-demo",
"productName": "ElectronDemo",
"copyright": "Copyright © 2024 Rex Wang",
"mac": {
"category": "public.app-category.utilities"
},
"nsis": {
"oneClick": false,
"allowToChangeInstallationDirectory": true
},
"files": [
"dist/**/*",
"electron/**/*"
],
"directories": {
"buildResources": "assets",
"output": "dist_electron"
}
}

配置详解:

  • appId: 应用的全局唯一标识符,常用反向域名格式。
  • productName: 应用的名称。
  • copyright: 版权信息。
  • mac/nsis: 平台特定的配置项,如 macOS 应用类别、Windows 安装程序配置等。
  • files: 指定包含在最终应用包中的文件和目录。
  • directories: 定义资源目录和输出目录,便于管理打包资源。

多平台打包

根据需要打包的平台,可以在 package.json 中设置特定的构建目标和体系结构:

  • Mac: 支持 ARM 和 Intel 架构。
  • Windows: 支持常见体系结构,可打包成安装程序或便携式应用。
  • Linux: 支持 .deb.AppImage 格式。

例如,Mac 平台的配置示例:

1
2
3
4
5
6
7
"mac": {
"category": "public.app-category.utilities",
"target": [
{"target": "dmg", "arch": ["x64", "arm64"]},
{"target": "dir", "arch": ["x64", "arm64"]}
]
}

执行打包

通过下列命令启动打包过程:

1
npm run electron:build

打包工具会根据当前操作系统和设置的配置自动选择合适的打包方式。例如,ARM 架构的 Mac 输出如下:

1
2
• building        target=macOS zip arch=arm64 file=dist_electron/ElectronDemo-0.0.0-arm64-mac.zip
• Detected arm64 process, HFS+ is unavailable. Creating dmg with APFS - supports Mac OSX 10.12+

完成打包后,dist_electron 目录下将包含所有生成的文件,例如 Mac 平台的输出结构如下所示:

1
2
3
4
5
6
7
dist_electron
├── ElectronDemo-0.0.0-arm64.dmg
├── ElectronDemo-0.0.0.dmg
├── mac
│ └── ElectronDemo.app
└── mac-arm64
└── ElectronDemo.app

.app 文件可直接运行,而 .dmg 文件提供了标准的安装流程。类似地,Linux 平台会生成 .AppImage 和其他分发格式。由于 Electron 应用内嵌了浏览器,打包文件的体积通常较大,例如 Linux 和 Mac 平台的 .AppImage/.dmg 文件大小通常在 100MB 左右。

小结

本例使用 Electron 框架将一个 Vue.js 项目转换成一个跨平台的桌面应用。

关键步骤回顾:

  1. 初始化:创建项目,打包运行,并用 Electron 运行
  2. 热更新开发:设置热更新,利用环境变量和配置文件适配开发和生产环境
  3. 打包与分发:使用 electron-builder 和相关工具,将应用打包成可分发的格式,支持多平台发布。

简单来说,在原项目基础上,安装 Electron 依赖,并添加配置文件 main.js, preload.js 然后打包构建。

Electron Forge

参考文档:

简介

Electron Forge 是一个全功能的工具集,专为 Electron 应用的开发、打包和分发而设计。它整合了多个底层 Electron 工具(如 @electron/packager、@electron/osx-sign 和 electron-winstaller)到一个统一的命令行界面中,极大简化了开发和部署流程。

准备工作

首先,将项目环境重新为基于 Vue 的开发环境,随后加入 Electron 的支持。这部分上一章已经详细介绍过,包括安装必要依赖,添加 main.jspreload.js 文件,修改 package.json 文件,支持 electron 热更新开发,只是去掉了 electron-builder 的配置。

安装依赖

安装 @electron-forge/cli

1
npm install --save-dev @electron-forge/cli

npx electron-forge import 命令将现有的 Electron 项目转换为 Electron Forge 项目。这一步会自动生成 forge.config.js 配置文件。

1
npx electron-forge import

安装额外依赖,根据目标平台,安装相应的打包工具(makers)。

1
2
3
4
5
6
7
# 可以写成一行,这里分开写方便理解
npm install --save-dev electron-squirrel-startup
npm install --save-dev @electron-forge/maker-squirrel
npm install --save-dev @electron-forge/maker-deb
npm install --save-dev @electron-forge/maker-rpm
npm install --save-dev @electron-forge/maker-zip
npm install --save-dev @electron-forge/maker-dmg

支持的应用列表

这些依赖的用处如下,根据需要,选择合适的打包工具(maker),参考 Maker 文档

包名 后缀 说明
electron-squirrel-startup N/A 管理 Windows 平台下的 Squirrel 安装过程
@electron-forge/maker-squirrel .exe Windows 的 Squirrel 安装包
@electron-forge/maker-deb .deb Debian-based Linux 系统的 DEB 包
@electron-forge/maker-rpm .rpm RPM-based Linux 系统的 RPM 包
@electron-forge/maker-zip .zip 为各平台创建 ZIP 压缩包
@electron-forge/maker-dmg .dmg macOS 的 DMG 镜像文件
@electron-forge/maker-flatpak .flatpak Linux 的 Flatpak 包
@electron-forge/maker-snap .snap Linux 的 Snapcraft 包
@electron-forge/maker-appx .appx Windows Store 的 AppX 安装程序

注意,跨平台的构建通常还要安装拓展的包:

  • DMG 文件只能在 macOS 计算机上构建
  • 在 Mac 上构建 Windows 的安装包,需安装 winemono
  • 在 Mac 上构建 Linux 的安装包,需安装 dpkg, fakeroot

修改配置

维护元数据,在 package.json 文件中更新 authordescription 字段,帮助用户和其他开发者了解项目的基本信息。而且 Windows 平台的构建,这两个参数是必填的。

使用默认参数打包

简单地运行以下命令:

1
2
npm run build
npm run make # npx electron-forge make

electron-forge make 命令背后包含了两个步骤:

  1. 在后台执行 electron-forge package,将应用代码与 Electron 二进制文件捆绑在一起。打包后的代码会被输出到一个文件夹中。
  2. 使用该文件夹为每个配置的创建一个单独的可分发文件。

mac 系统下,产出的文件结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
out
├── electron-demo-darwin-arm64
│   ├── LICENSE
│   ├── LICENSES.chromium.html
│   ├── electron-demo.app
│   └── version
└── make
└── zip
└── darwin
└── arm64
└── electron-demo-darwin-arm64-0.0.0.zip

5 directories, 3 files

如果只构建一个平台,可将 npm run build 写在 npm run make 里,一键完成构建。但如果要打包多个平台,则建议分开,npm run build 命令只需执行一次。

支持的架构列表

Make 参数文档:https://www.electronforge.io/cli#make

forge.config.js 中为不同的平台配置特定的打包工具(maker)。例如,以下配置为 macOS 和 Linux 平台创建 ZIP 压缩包:

1
2
3
4
5
6
7
8
9
10
11
module.exports = {
makers: [
{
name: '@electron-forge/maker-zip',
platforms: ['darwin', 'linux'],
config: {
// 特定配置
}
}
]
};

支持的配置选项如下:

参数 取值 描述
--arch 如 x64 目标架构。默认为您当前的架构("host"架构)。允许的值包括:“ia32”, “x64”, “armv7l”, “arm64”, “universal”, 或 “mips64el”。如果有多个值,应用逗号分隔。
--platform 如 mas 目标平台。通常,您只能在平台 X 上为平台 X 制作包。默认为您正在运行的平台("host"平台)。
--targets 制作目标的逗号分隔列表 为此次运行覆盖制作目标。制作工具名是完整的 node 模块名,如 @electron-forge/maker-deb。默认情况下,使用的制作目标是为给定平台配置和可用的目标。
--skip-package N/A 如果您希望跳过打包步骤,可设置此选项,特别是在连续执行多次打包时可以节省时间。默认不跳过打包。

基本用法示例:

1
2
# 默认情况下,make 命令对应一个 npm 脚本:
npm run make -- --arch="ia32"

设置应用图标

参考文档: Custom App Icons

为 Electron 应用设置专业的图标,需要按照特定的格式和大小标准进行创建。以下是每个操作系统推荐的文件格式和图标大小:

操作系统 格式 大小
macOS .icns 512x512 像素(视网膜显示屏为 1024x1024)
Windows .ico 256x256 像素
Linux .png 512x512 像素

对于 Windows 和 macOS,可以在 forge.config.js 中配置图标路径。由于 Electron Forge 会自动为每个平台添加正确的扩展名,因此无需在路径中包含 .ico.icns 后缀。

1
2
3
4
5
6
7
module.exports = {
// 其他配置...
packagerConfig: {
icon: '/path/to/icon' // 路径中不包括文件扩展名
}
// 其他配置...
};

可以用相对 forge.config.js 文件的路径,或者绝对路径。可以省略扩展名,以同时支持多个平台。

对于 Linux,配置图标的路径则需要在 forge.config.js 中指定:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
module.exports = {
// 其他配置...
makers: [
{
name: '@electron-forge/maker-deb',
config: {
options: {
icon: '/path/to/icon.png'
}
}
}
]
// 其他配置...
}

同时,在实例化 BrowserWindow 时,也需要指定图标:

1
2
3
4
5
6
7
// main.js
const { BrowserWindow } = require('electron')

const win = new BrowserWindow({
// 其他配置...
icon: '/path/to/icon.png'
});

此外,安装程序的图标配置可以单独配置,详见文档

附:图标转化

Windows 的 .ico 文件可直接用 ImageMagick 转换:

1
2
3
4
5
# 安装 ImageMagick
# brew install imagemagick # macOS
# sudo apt-get install imagemagick # Ubuntu
convert avatar.png output.ico
convert avatar.png -define icon:auto-resize="256,128,64,48,32,16" output.icns

macOS 的 .icns 可以用 png2icns 来转化:

1
2
npm install png2icns -g
png2icns /path/to/icon.png -s 16,32,64,128,256

但实测部分图标会转化失败。可以手写脚本,基于系统自带的 sipsiconutil 工具来转换图标:

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
#!/bin/bash

# 检查参数是否传入及图片文件是否存在
if [ "$#" -lt 1 ] || [ ! -f "$1" ]; then
echo "用法: $0 <图片路径> [最大尺寸]"
exit 1
fi

PIC_FILE=$1
MAX_SIZE=${2-1024} # 设置默认最大尺寸为1024

# 检查 sips 和 iconutil 命令是否存在
if ! command -v sips &> /dev/null || ! command -v iconutil &> /dev/null; then
echo "sips 或 iconutil 工具不存在。脚本需要在 macOS 上运行。"
exit 1
fi

# 转换图片到不同的尺寸并创建 icns 文件
mkdir -p tmp.iconset &&
for sz in 16 32 64 128 256 512 1024; do
if [ $sz -le $MAX_SIZE ]; then
sips -z $sz $sz "$PIC_FILE" --out tmp.iconset/icon_${sz}x${sz}.png
fi
if [ $sz -ge 32 ] && [ $(($sz * 2)) -le $MAX_SIZE ]; then
sips -z $(($sz * 2)) $(($sz * 2)) "$PIC_FILE" --out tmp.iconset/icon_${sz}x${sz}@2x.png
fi
done &&
iconutil -c icns tmp.iconset -o Icon.icns && rm -r tmp.iconset

不同平台的打包实战

macOS 平台

针对 macOS 平台,需要分别考虑 ARM 和 Intel 架构。以下命令将分别为这两种架构生成安装包:

1
2
3
4
5
6
7
8
# 为 macOS Intel 架构打包
npx electron-forge make --platform=darwin --arch=x64 --targets="@electron-forge/maker-dmg" --icon=public/rex

# 为 macOS ARM 架构打包
npx electron-forge make --platform=darwin --arch=arm64 --targets="@electron-forge/maker-dmg" --icon=public/rex

# 为 macOS ARM 架构打包 | 输出 .app 可执行文件
npx electron-forge make --platform=darwin --arch=arm64 --targets="@electron-forge/maker-zip" --icon=public/rex

Windows 平台打包

Windows 7 和 Windows 10 系统,可以使用以下命令进行打包:

1
2
3
4
5
# 打包为 Windows 安装程序 (x64)
npx electron-forge make --platform=win32 --arch=x64 --targets="@electron-forge/maker-squirrel" --icon=public/rex

# 打包为 Windows 安装程序 (x86)
npx electron-forge make --platform=win32 --arch=ia32 --targets="@electron-forge/maker-squirrel" --icon=public/rex

Ubuntu Linux 平台打包

对于 Ubuntu Linux,我们将打包为 .deb 格式,适用于基于 Debian 的系统:

1
2
# 打包为 Ubuntu .deb 包
npx electron-forge make --platform=linux --arch=x64 --targets="@electron-forge/maker-deb" --icon=public/rex

小结

以上,根据不同的操作系统和架构需求,为 Electron 应用创建安装包。更详细的配置和参数设置,可参考 Electron Forge 文档

自动化部署

在软件开发中,自动化是提升效率和产出质量的关键,本章我们将详细介绍如何自动化构建和发布 Electron 应用。

GitHub Actions 简介

GitHub Actions 是一个集成的 CI/CD 服务,允许开发者在 GitHub 仓库中自动化、定制和执行软件开发工作流程。通过创建 workflows,可以在代码提交后自动启动构建过程,测试代码,甚至部署到生产环境,极大地提高开发效率和部署频率。

更深入的自动化测试可以参考官方文档:

类似平台如 Jenkins、CircleCI、Travis CI 以及 GitLab Runner 等也有广泛的应用,本教程将专注于介绍 GitHub Actions。

使用限制

在使用 GitHub Actions 时,需要了解一些基本的使用限制和计费信息(参考文档)。

保存期限

默认情况下,GitHub Actions 生成的工作流日志和项目文件将保存 90 天,之后自动删除。不过,这个期限可以根据仓库的属性和用户的需要调整:

  • 公共仓库:对于托管在 GitHub 的公共仓库,使用 GitHub 托管的运行器完全免费,日志保存期限可以设定在 1 至 90 天之间。
  • 私人仓库:私人仓库可以根据账户的计划享受一定量的免费分钟数和存储空间。超出这些限制则需要支付额外费用,而日志的保存期限可以设定在 1 至 400 天之间。

并发限制

GitHub Actions 对并发作业的数量有一定的限制,这取决于用户的 GitHub 计划:

GitHub 计划 标准托管运行器总并发作业 macOS 最大并发作业 GPU 最大并发作业
免费 20 5 N/A
专业版 40 5 N/A
团队 60 / 1000 5 100
企业 500 / 1000 50 100

可以在账号设置的billing-summary 中查看具体限制,比如

GitHub Pro GitHub Free
无限制的公开/私有仓库 无限制的公开/私有仓库
无限制的协作者 无限制的协作者
3,000分钟/月 的 GitHub Actions 使用时间 2,000分钟/月 的 GitHub Actions 使用时间
2GB 的 Packages 存储空间 500MB 的 Packages 存储空间
180 核心小时的 Codespaces 计算时间 120 核心小时的 Codespaces 计算时间
20GB 的 Codespaces 存储空间 15GB 的 Codespaces 存储空间
社区支持 N/A

注:用 GITHUB 学生包白嫖的 4$/月的 Pro 会员。

自动构建的配置

为了提高工作流程的可读性并简化脚本配置,我们选择使用 npx electron-forge make 命令来执行构建任务,而不是在 package.json 中配置的 npm run make

注意事项

在设置 forge.config.js 文件时,特别是配置 makers 字段,如果指定了特定平台的构建目标,如仅限 Linux:

1
2
3
4
5
6
makers: [
{
name: '@electron-forge/maker-zip',
platforms: ['linux'],
}
]

这样的配置在尝试在 macOS 上执行构建时可能会引发错误。为了避免这种情况,在多平台构建场景下,建议不要指定 platforms 字段,或适当调整该配置,甚至可以考虑删除该字段。

macOS 平台的 GitHub Actions 示例

下面是一个工作流示例,在 macOS 平台上针对不同架构(x64 和 arm64)及目标格式(DMG 和 ZIP)进行构建:

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
43
44
45
46
name: macOS Build

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
build-macos:
runs-on: macos-latest
strategy:
matrix:
arch: [x64, arm64]
target: [dmg, zip]

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '20'

- name: Install Python 3.11.4
uses: actions/setup-python@v4
with:
python-version: '3.11.4'

- name: Install dependencies
run: npm install

- name: Build application
run: npm run build

- name: Package application for macOS ${{ matrix.arch }} ${{ matrix.target }}
run: npx electron-forge make --platform=darwin --arch=${{ matrix.arch }} --targets="@electron-forge/maker-${{ matrix.target }}" --icon=public/avatar

- name: Upload Artifacts
uses: actions/upload-artifact@v3
with:
name: electron-app-${{ matrix.arch }}-${{ matrix.target }}
path: ${{ github.workspace }}/**/make/**/*.${{ matrix.target == 'dmg' && 'dmg' || 'zip' }}

构建顺利的话,在工作流底部能看到产出文件

20240511040008

常见错误及解决方案

在首次编写和测试工作流脚本时,可能会遇到如下构建错误:

1
2
3
✔ Finalizing package
✖ Making a dmg distributable for darwin/arm64 [FAILED: Cannot find module 'appdmg']
✔ Packaging for arm64 on darwin

根据官方 Issue “Cannot find module ‘appdmg’”,这是由 GitHub 的 macOS 镜像配置引起的。解决这一问题的方法包括使用指定版本的 macOS 容器,或更改默认的 Python 版本,如本示例中所采用的后者方法。

类似可根据需要修改为 Windows 和 Linux 平台的脚本,在配置这些脚本时,Python 的这一步可以省略。

自动发布

使用 Electron Forge 的官方插件发布到 GitHub 是一种简单且高效的方式。

关联文档:

设置 GitHub 令牌

首先,需要在 GitHub 创建一个个人访问令牌(Personal Access Token),以授权 GitHub Actions 自动发布应用。可以通过以下链接创建新的访问令牌:Create New Token

20240511045447

创建时,请确保至少启用以下权限:

  • Contents: 允许访问仓库内容,提交,分支,下载,发布和合并。

GitHub Token Permissions

在 GitHub Actions YAML 配置文件中设置 GITHUB_TOKEN 环境变量,以使用这个令牌。

配置自动发布

使用 Electron Forge 的 GitHub Publisher 插件可以简化发布过程。首先,需要安装这个插件:

1
npm install --save-dev @electron-forge/publisher-github

接着,在 package.json 中添加相应的脚本来支持自动发布:

1
2
3
4
5
6
"scripts": {
"start": "electron-forge start",
"package": "electron-forge package",
"make": "electron-forge make",
"publish": "electron-forge publish"
},

forge.config.js 文件中配置发布选项:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
module.exports = {
publishers: [
{
name: '@electron-forge/publisher-github',
config: {
repository: {
owner: 'github-user-name',
name: 'github-repo-name'
},
prerelease: false,
draft: true
}
}
]
}

在 GitHub 中创建 Release 的这两个选项 draftprerelease

  • Draft 指一个还未完成的 Release。当你创建一个草稿 Release 时,它不会对你的用户公开显示,只有拥有仓库写权限的用户可以看到和编辑它。这允许你或你的团队在公开之前仔细审查和完善发布内容。
  • Prerelease 用于标识尚未完全稳定、可能还在测试或开发中的 Release。尽管它是公开的,用户可以看到并下载,但通过标记为预发布,你可以明确告知用户这不是最终的稳定版本,可能还存在一些未解决的问题或需要进一步测试。

添加仓库信息

package.json 中添加或更新以下信息,确保项目描述和仓库信息正确无误:

1
2
3
4
5
6
"author": "Rex Wang",
"description": "An electron demo with vite and vue3",
"repository": {
"type": "git",
"url": "https://github.com/rexwzh/electron-demo.git"
},

执行发布

设置好环境变量后,使用以下命令推送更新并自动发布:

1
2
export GITHUB_TOKEN=github_xxxxxx
npx electron-forge publish --platform=darwin --arch=arm64 --targets="@electron-forge/maker-zip" --icon=public/avatar

当然,这些在命令行执行的操作,都可以在 GitHub Actions 中配置,实现自动化发布。参考代码:Electron-demo

配置自动更新

Electron 提供了一个 autoUpdater 模块,用于获取和安装更新。为了简化自动更新的实现,Electron 社区提供了一个实用的模块 update-electron-app,它自动配置 autoUpdater 来使用 update.electronjs.org 服务。

首先,需要安装 update-electron-app 模块:

1
npm install update-electron-app --save-dev

在主进程文件 main.js 中,引入并初始化 update-electron-app

1
2
const { updateElectronApp } = require('update-electron-app')
updateElectronApp()

该函数调用将配置 autoUpdater,以自动从与项目的 package.json 中的 "repository" 字段匹配的 URL 检查更新。

相关文档:


以上,代码细节可以查看:RexWzh/Electron-demo