Electron 详解:桌面应用的开发利器
初探 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 | ❯ npm -v |
npm
使用低版本,避免一些卡顿问题。
创建应用
本示例使用 Vue 和 JavaScript:
1 | npm create vite@latest electron-demo |
项目的目录结构如下所示:
1 | . |
最初考虑使用 pnpm
来实践,但由于 pnpm
对 Electron 的支持存在问题,暂时放弃,详情参阅:知乎文章。
安装与启动
建议配置 npm 镜像以加速下载过程:
1 | # npm config set registry https://r.cnpmjs.org |
安装 Electron 过程中的下载可能需要较长时间:
1 | npm install electron |
添加和修改 Electron 配置
这份代码可以参考官网给的 examples。
为了确保 Electron 应用能够正确地引用资源文件(如 CSS 和 JavaScript),需要对 vite.config.js
文件进行适当的修改。这包括设置资源的加载路径为相对路径,以预防文件找不到的问题。
修改 vite.config.js
如下:
1 | import { defineConfig } from 'vite' |
接下来,我们需要添加一个 main.js
文件,这个文件是 Electron 应用的入口,负责控制应用生命周期和创建原生浏览器窗口。
1 | // main.js |
添加 preload.js
文件以在渲染进程中安全地使用 Node.js 模块:
1 | // preload.js |
最后,更新 package.json
文件以包括新的启动脚本,使 Electron 能够运行。
1 | { |
打包和运行 Vue 项目
为了部署 Electron 应用,首先需要对 Vue 项目进行打包。这可以通过以下命令实现:
1 | npm run build |
打包完成后,通过下列命令启动 Electron 应用:
1 | npm run electron:serve |
应用运行效果如图所示:
热更新开发
为了提升开发效率,可以设置热更新,使得在开发过程中对代码的修改能够即时反映在 Electron 应用中。首先需要修改 main.js
文件中的内容加载方式,从加载本地文件改为加载开发服务器地址:
1 | mainWindow.loadURL("http://localhost:5173") // 更改为开发服务器的 URL |
为了确保 Electron 能够在 Vite 开发服务器启动后运行,需引入 concurrently
和 wait-on
两个 npm 包。concurrently
允许同时运行多个命令,而 wait-on
确保 Electron 在服务器可访问后再启动。
首先,安装这两个工具:
1 | npm install -D concurrently wait-on |
然后,更新 package.json
中的 scripts
部分,添加用于启动开发环境的命令:
1 | "electron": "wait-on tcp:5173 && electron .", // 新增,等待端口5173 |
现在,通过执行 npm run electron:serve
,Electron 应用将自动启动并加载 Vite 的开发服务器,实现实时的热更新功能。
环境分离和打包配置
在开发和生产环境中运行 Electron 应用通常需要不同的配置。特别是在涉及到资源加载方式时,比如开发环境中可能从本地服务器加载,而生产环境则从文件系统加载打包后的资源。
环境变量设置
为了在不同环境下切换配置,我们使用 NODE_ENV
环境变量来区分生产环境 (production
) 和开发环境 (development
)。您也可以根据需要配置额外的环境,如 release
。
首先,我们组织 Electron 相关的文件到一个单独的目录以便管理:
1 | # 在项目根目录下操作 |
修改 main.js
文件以使用环境变量来决定加载的资源类型:
1 | const { app, BrowserWindow } = require('electron') |
更新 package.json
更新 package.json
来适应新的文件结构,并确保 NODE_ENV
在启动时正确设置:
1 | { |
当设置环境变量 const NODE_ENV = 'development'
时,热更新效果:
应用打包
打包 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 | "build": { |
配置详解:
- appId: 应用的全局唯一标识符,常用反向域名格式。
- productName: 应用的名称。
- copyright: 版权信息。
- mac/nsis: 平台特定的配置项,如 macOS 应用类别、Windows 安装程序配置等。
- files: 指定包含在最终应用包中的文件和目录。
- directories: 定义资源目录和输出目录,便于管理打包资源。
多平台打包
根据需要打包的平台,可以在 package.json
中设置特定的构建目标和体系结构:
- Mac: 支持 ARM 和 Intel 架构。
- Windows: 支持常见体系结构,可打包成安装程序或便携式应用。
- Linux: 支持
.deb
和.AppImage
格式。
例如,Mac 平台的配置示例:
1 | "mac": { |
执行打包
通过下列命令启动打包过程:
1 | npm run electron:build |
打包工具会根据当前操作系统和设置的配置自动选择合适的打包方式。例如,ARM 架构的 Mac 输出如下:
1 | • building target=macOS zip arch=arm64 file=dist_electron/ElectronDemo-0.0.0-arm64-mac.zip |
完成打包后,dist_electron
目录下将包含所有生成的文件,例如 Mac 平台的输出结构如下所示:
1 | dist_electron |
.app
文件可直接运行,而 .dmg
文件提供了标准的安装流程。类似地,Linux 平台会生成 .AppImage
和其他分发格式。由于 Electron 应用内嵌了浏览器,打包文件的体积通常较大,例如 Linux 和 Mac 平台的 .AppImage/.dmg
文件大小通常在 100MB 左右。
小结
本例使用 Electron 框架将一个 Vue.js 项目转换成一个跨平台的桌面应用。
关键步骤回顾:
- 初始化:创建项目,打包运行,并用 Electron 运行
- 热更新开发:设置热更新,利用环境变量和配置文件适配开发和生产环境
- 打包与分发:使用
electron-builder
和相关工具,将应用打包成可分发的格式,支持多平台发布。
简单来说,在原项目基础上,安装 Electron 依赖,并添加配置文件 main.js, preload.js
然后打包构建。
Electron Forge
参考文档:
简介
Electron Forge 是一个全功能的工具集,专为 Electron 应用的开发、打包和分发而设计。它整合了多个底层 Electron 工具(如 @electron/packager、@electron/osx-sign 和 electron-winstaller)到一个统一的命令行界面中,极大简化了开发和部署流程。
准备工作
首先,将项目环境重新为基于 Vue 的开发环境,随后加入 Electron 的支持。这部分上一章已经详细介绍过,包括安装必要依赖,添加 main.js
和 preload.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 | # 可以写成一行,这里分开写方便理解 |
支持的应用列表
这些依赖的用处如下,根据需要,选择合适的打包工具(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 的安装包,需安装
wine
和mono
- 在 Mac 上构建 Linux 的安装包,需安装
dpkg, fakeroot
修改配置
维护元数据,在 package.json
文件中更新 author
和 description
字段,帮助用户和其他开发者了解项目的基本信息。而且 Windows 平台的构建,这两个参数是必填的。
使用默认参数打包
简单地运行以下命令:
1 | npm run build |
electron-forge make
命令背后包含了两个步骤:
- 在后台执行
electron-forge package
,将应用代码与 Electron 二进制文件捆绑在一起。打包后的代码会被输出到一个文件夹中。 - 使用该文件夹为每个配置的创建一个单独的可分发文件。
mac 系统下,产出的文件结构:
1 | out |
如果只构建一个平台,可将 npm run build
写在 npm run make
里,一键完成构建。但如果要打包多个平台,则建议分开,npm run build
命令只需执行一次。
支持的架构列表
Make 参数文档:https://www.electronforge.io/cli#make
在 forge.config.js
中为不同的平台配置特定的打包工具(maker)。例如,以下配置为 macOS 和 Linux 平台创建 ZIP 压缩包:
1 | module.exports = { |
支持的配置选项如下:
参数 | 取值 | 描述 |
---|---|---|
--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 | # 默认情况下,make 命令对应一个 npm 脚本: |
设置应用图标
参考文档: Custom App Icons
为 Electron 应用设置专业的图标,需要按照特定的格式和大小标准进行创建。以下是每个操作系统推荐的文件格式和图标大小:
操作系统 | 格式 | 大小 |
---|---|---|
macOS | .icns |
512x512 像素(视网膜显示屏为 1024x1024) |
Windows | .ico |
256x256 像素 |
Linux | .png |
512x512 像素 |
对于 Windows 和 macOS,可以在 forge.config.js
中配置图标路径。由于 Electron Forge 会自动为每个平台添加正确的扩展名,因此无需在路径中包含 .ico
或 .icns
后缀。
1 | module.exports = { |
可以用相对 forge.config.js
文件的路径,或者绝对路径。可以省略扩展名,以同时支持多个平台。
对于 Linux,配置图标的路径则需要在 forge.config.js
中指定:
1 | module.exports = { |
同时,在实例化 BrowserWindow
时,也需要指定图标:
1 | // main.js |
此外,安装程序的图标配置可以单独配置,详见文档。
附:图标转化
Windows 的 .ico
文件可直接用 ImageMagick 转换:
1 | # 安装 ImageMagick |
macOS 的 .icns
可以用 png2icns
来转化:
1 | npm install png2icns -g |
但实测部分图标会转化失败。可以手写脚本,基于系统自带的 sips
和 iconutil
工具来转换图标:
1 |
|
不同平台的打包实战
macOS 平台
针对 macOS 平台,需要分别考虑 ARM 和 Intel 架构。以下命令将分别为这两种架构生成安装包:
1 | # 为 macOS Intel 架构打包 |
Windows 平台打包
Windows 7 和 Windows 10 系统,可以使用以下命令进行打包:
1 | # 打包为 Windows 安装程序 (x64) |
Ubuntu Linux 平台打包
对于 Ubuntu Linux,我们将打包为 .deb 格式,适用于基于 Debian 的系统:
1 | # 打包为 Ubuntu .deb 包 |
小结
以上,根据不同的操作系统和架构需求,为 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 | makers: [ |
这样的配置在尝试在 macOS 上执行构建时可能会引发错误。为了避免这种情况,在多平台构建场景下,建议不要指定 platforms
字段,或适当调整该配置,甚至可以考虑删除该字段。
macOS 平台的 GitHub Actions 示例
下面是一个工作流示例,在 macOS 平台上针对不同架构(x64 和 arm64)及目标格式(DMG 和 ZIP)进行构建:
1 | name: macOS Build |
构建顺利的话,在工作流底部能看到产出文件
常见错误及解决方案
在首次编写和测试工作流脚本时,可能会遇到如下构建错误:
1 | ✔ Finalizing package |
根据官方 Issue “Cannot find module ‘appdmg’”,这是由 GitHub 的 macOS 镜像配置引起的。解决这一问题的方法包括使用指定版本的 macOS 容器,或更改默认的 Python 版本,如本示例中所采用的后者方法。
类似可根据需要修改为 Windows 和 Linux 平台的脚本,在配置这些脚本时,Python 的这一步可以省略。
自动发布
使用 Electron Forge 的官方插件发布到 GitHub 是一种简单且高效的方式。
关联文档:
- 官方教程 Publishing and Updating
- GitHub 插件:https://update.electronjs.org
- 其他平台:官方插件 Publishers
设置 GitHub 令牌
首先,需要在 GitHub 创建一个个人访问令牌(Personal Access Token),以授权 GitHub Actions 自动发布应用。可以通过以下链接创建新的访问令牌:Create New Token。
创建时,请确保至少启用以下权限:
- Contents: 允许访问仓库内容,提交,分支,下载,发布和合并。
在 GitHub Actions YAML 配置文件中设置 GITHUB_TOKEN
环境变量,以使用这个令牌。
配置自动发布
使用 Electron Forge 的 GitHub Publisher 插件可以简化发布过程。首先,需要安装这个插件:
1 | npm install --save-dev @electron-forge/publisher-github |
接着,在 package.json
中添加相应的脚本来支持自动发布:
1 | "scripts": { |
在 forge.config.js
文件中配置发布选项:
1 | module.exports = { |
在 GitHub 中创建 Release 的这两个选项 draft
和 prerelease
:
- Draft 指一个还未完成的 Release。当你创建一个草稿 Release 时,它不会对你的用户公开显示,只有拥有仓库写权限的用户可以看到和编辑它。这允许你或你的团队在公开之前仔细审查和完善发布内容。
- Prerelease 用于标识尚未完全稳定、可能还在测试或开发中的 Release。尽管它是公开的,用户可以看到并下载,但通过标记为预发布,你可以明确告知用户这不是最终的稳定版本,可能还存在一些未解决的问题或需要进一步测试。
添加仓库信息
在 package.json
中添加或更新以下信息,确保项目描述和仓库信息正确无误:
1 | "author": "Rex Wang", |
执行发布
设置好环境变量后,使用以下命令推送更新并自动发布:
1 | export GITHUB_TOKEN=github_xxxxxx |
当然,这些在命令行执行的操作,都可以在 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 | const { updateElectronApp } = require('update-electron-app') |
该函数调用将配置 autoUpdater
,以自动从与项目的 package.json
中的 "repository"
字段匹配的 URL 检查更新。
相关文档:
- 官方
autoUpdater
文档:autoUpdater update-electron-app
项目地址:update-electron-app on GitHub
以上,代码细节可以查看:RexWzh/Electron-demo 。