前言
刚开始接触 Electron 的小伙伴们,通常会直接查看 Electron 官网进行学习,可是官网的示例都是基于纯 JavaScript 进行实现。我相信很多小伙伴会跟我一样,自从接触了框架之后,再用纯 JS 代码进行开发,会非常的痛苦。Electron 官方也意识到,现在绝大多数开发者都会使用框架和打包工具进行开发,刚入手 Electron 的开发者们很难将这些技术融入其中。于是,Electron Forge 诞生了!
Electron Forge 不仅支持 Webpack 和 Vite 打包工具,还支持 React 和 Vue 框架。
由于作者主要使用 Vue 3 进行开发,本篇文章主要基于 Electron Forge 的 Vite 模板进行 Vue 3 环境的搭建。(本篇文章对官网的示例稍作修改,不喜欢的小伙伴可自行去官网进行学习。)
Electron 网址:https://www.electronjs.org
Electron Forge 网址:https://www.electronforge.io
1. 初始化
1.1 使用 Electron Forge 的 Vite 模板
npm init electron-app@latest 项目名称 -- --template=vite
1.2 添加依赖项
# 跳转至项目目录
cd 项目名称
# vue 依赖
npm install vue
# vite vue3 插件
npm install --save-dev @vitejs/plugin-vue
1.3 集成 Vue 3 代码
1.3.1 将 src/index.html 的内容替换为具有 #app id 属性的 div 元素
src/index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>你好!世界!</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/renderer.js"></script>
</body>
</html>
1.3.2 将模板生成的内容添加到 src/App.vue
src/App.vue
<script setup>
console.log("👋 该日志由 App.vue 记录。")
</script>
<template>
<h1>💖 你好!世界! 💖</h1>
<p>欢迎使用你的 Electron 程序。</p>
</template>
1.3.3 使用 Vue 的 createApp API 将 App.vue 挂载到 DOM 中
src/renderer.js
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.mount('#app')
1.3.4 为 Vite.js 配置 Vue 插件
vite.renderer.config.mjs
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config
export default defineConfig({
plugins: [vue()]
})
2. 运行
npm run start
3. 打包
3.1 打包方式
3.1.1 Zip - maker-zip
使用 Electron Forge 为你的 Electron 应用程序创建一个 ZIP 文件。
Zip 目标构建包含打包应用程序的基本 .zip 文件。使用此制作工具没有特定于平台的依赖项,它将在任何平台上运行。
3.1.2 Squirrel.Windows - maker-squirrel
使用 Electron Forge 为你的 Electron 应用程序创建一个 Windows 安装程序。
Squirrel.Windows 目标使用 Squirrel.Windows 框架。它生成三个文件:
文件 | 描述 |
---|---|
{appName} Setup.exe | 应用程序的主要可执行安装程序 |
{appName}-full.nupkg | 用于更新的 NuGet 包文件 |
RELEASES | 用于检查更新是否可用的元数据文件 |
Squirrel.Windows 是一种无提示、无麻烦、无管理员的 Windows 应用程序安装方法,因此是你可以获得的最用户友好的方法。你只能在 Windows 计算机或安装了 mono 和 wine 的 Linux 计算机上生成 Squirrel.Windows 目标。
3.1.3 WiX MSI - maker-wix
使用 Electron Forge 在 Windows 上为你的 Electron 应用程序创建一个 MSI 文件。
WiX MSI 目标构建 .msi 文件,这些文件是“传统” Windows 安装程序文件。请注意,建议使用 Squirrel.Windows。这些 MSI 文件对于安装来说是一种较差的用户体验,但有时有必要构建 MSI 文件,以安抚大型企业公司与内部应用程序分发策略。你只能在安装了 WiX 工具包中的 light 和 candle 的机器上构建 WiX MSI 目标。
3.1.4 AppX - maker-appx
使用 Electron Forge 为 Electron 应用的 Windows 应用商店创建程序包。
AppX 目标构建 .appx 包,旨在面向 Windows 应用商店的包。只能在安装了 Windows 10 SDK 的 Windows 计算机上生成 AppX 目标。查看electron-windows-store 文档 了解有关平台要求的更多信息。
3.1.5 DMG - maker-dmg
使用 Electron Forge 生成 DMG,以便在 macOS 上分发你的 Electron 应用程序。
DMG 目标构建 .dmg 文件,这是共享 macOS 应用的标准格式。DMG 的作用类似于 zip 文件,但为用户提供了一种简单的方法,可以获取应用程序并将其放在 /Applications 目录中。
3.1.6 Pkg - maker-pkg
使用 Electron Forge 在 macOS 上为你的 Electron 应用程序创建一个 PKG 文件。
Pkg 目标为 macOS 构建 .pkg 文件。这些用于将你的应用程序上传到 Mac App Store,或者仅作为 macOS 用户的替代分发方法。你只能在 macOS 计算机上构建 Pkg 目标,同时以 darwin 或 mas 平台为目标。
3.1.7 Snapcraft - maker-snap
使用 Electron Forge 为你的 Electron 应用程序创建一个 Snap 包。
Snapcraft 目标构建 .snap 文件,这是由 Ubuntu 背后的公司 Canonical 创建和赞助的打包格式。它是一种沙盒包格式,允许各种 Linux 发行版的用户在其计算机上的隔离环境中安装应用程序。你只能在安装了 snapcraft 软件包的 Linux 系统上构建 Snapcraft 目标。
3.1.8 RPM - maker-rpm
使用 Electron Forge 为你的 Electron 应用程序创建基于 RedHat 的 Linux 发行版的 RPM 包。
RPM 目标构建 .rpm 文件,这是基于 Red Hat 的 Linux 发行版(如 Fedora 和 Red Hat Enterprise Linux(RHEL))的标准包格式。你只能在安装了 rpm 或 rpm-build 软件包的 Linux 计算机上构建 RPM 目标。
在 Fedora 上,你可以做这样的事情:
sudo dnf install rpm-build
在 Debian 或 Ubuntu 上,您需要执行以下操作:
sudo apt-get install rpm
3.1.9 deb - maker-deb
使用 Electron Forge 为你的 Electron 应用程序创建基于 Debian 的 Linux 发行版的软件包。
deb 目标构建 .deb 包,这是基于 Debian 的 Linux 发行版(如 Ubuntu)的标准包格式。你只能在安装了 fakeroot 和 dpkg 软件包的 Linux 或 macOS 机器上构建 deb 目标。
3.1.10 Flatpak - maker-flatpak
使用 Electron Forge 为你的 Electron 应用程序创建一个 Flatpak 应用程序。
Flatpak 目标构建 .flatpak 文件,这是 Linux 发行版的一种打包格式,允许在与系统其余部分隔离的情况下以沙盒方式安装应用程序。相比之下,典型的 deb 或 RPM 安装方法不是沙盒式的。只有当系统上安装了 flatpak、flatpak-builder 和 eu-strip(通常是 elfutils 软件包的一部分)时,才能构建 Flatpak 目标。
3.2 打包平台
darwin - maxOS
linux - Linux
win32 - Windows
3.3 自定义图标
可以使用在线找到的各种转换工具生成图标。建议先从 1024 x 1024px 的图像开始,然后再将其转换为各种尺寸。
3.3.1 支持更高的像素密度
在支持高 DPI 的平台(如 Apple Retina 显示屏)上,您可以在图像的基本文件名后附加 @2x 以将其标记为高分辨率图像。例如,如果 icon.png 是具有标准分辨率的普通图像,则 icon@2x.png 将被视为具有两倍 DPI 强度的高分辨率图像。
如果要同时支持不同 DPI 密度的不同显示器,可以将不同大小的图像放在同一个文件夹中,并使用不带 DPI 后缀的文件名。例如:
images/
├── icon.png
├── icon@2x.png
└── icon@3x.png
还支持 DPI 的以下后缀:
@1x、@1.25x、@1.33x、@1.4x、@1.5x、@1.8x、@2x、@2.5x、@3x、@4x 和 @5x。
3.3.2 支持的格式
每个平台的推荐文件格式和图标大小如下:
操作系统 | 格式 | 大小 |
---|---|---|
macOS | .icns | 512 x 512 像素(视网膜显示屏为 1024 x 1024) |
Windows | .ico | 256 x 256 像素 |
Linux | .png | 512 x 512 像素 |
3.3.3 刷新图标缓存 (Windows)
Windows 将所有应用程序图标缓存在隐藏的图标缓存数据库中。如果你的 Electron 应用程序的图标没有显示,你可能需要重建这个缓存。要使缓存失效,请使用系统 ie4uinit.exe 实用程序:
ie4uinit.exe -show
3.4 打包配置
两种配置任选一种即可
3.4.1 在 package.json 中进行配置
{
"config": {
"forge": {
"makers": [
{
"name": "@electron-forge/maker-zip",
// 打包方式对应的平台
"platforms": ["darwin", "linux", "win32"],
"config": {
// 配置详情
}
}
]
}
}
}
3.4.2 在 forge.config.js 中进行配置
module.exports = {
packagerConfig: {
// 应用程序图标
icon: 'public/icon/Stella.ico',
},
makers: [
{
name: '@electron-forge/maker-squirrel',
config: {
// 安装程序图标
setupIcon: 'public/icon/Stella.ico'
}
},
{
name: '@electron-forge/maker-zip',
// 打包方式对应的平台
platforms: ['darwin', 'linux']
}
]
}
3.5 打包命令
npm run make
4. 代码示例
目录
my-vue-app
├── .vite - Vite 生成文件
├── node_modules - node 模块
├── out - 打包文件
└── public - 公共资源
└── icon - 图标
└── xxx.ico - 应用程序图标
└── src - 主要代码
├── App.vue - Vue 根组件
├── main.js - Electron 主进程文件
├── preload.js - Electron 预加载文件
└── renderer.js - Vue 入口文件
├── .gitignore - git 忽略文件
├── forge.config.js - Electron Forge 配置文件
├── index.html - 主页面
├── package-lock.json - node 依赖详情
├── package.json - node 依赖
├── vite.main.config.mjs - Vite Electron 主进程配置
├── vite.preload.config.mjs - Vite 预加载文件配置
└── vite.renderer.config.mjs - Vite Vue 配置
src/App.vue
<script setup>
console.log("👋 该日志由 App.vue 记录。")
</script>
<template>
<h1>💖 你好!世界!</h1>
<p>欢迎使用你的 Electron 程序!</p>
</template>
src/main.js
const { app, BrowserWindow } = require('electron')
const path = require('path')
// 在安装/卸载时,Windows 上创建/删除快捷方式。
if (require('electron-squirrel-startup')) {
app.quit()
}
const createWindow = () => {
// 创建浏览器窗口。
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
}
})
// 加载应用程序的 index.html。
if (MAIN_WINDOW_VITE_DEV_SERVER_URL) {
mainWindow.loadURL(MAIN_WINDOW_VITE_DEV_SERVER_URL)
} else {
mainWindow.loadFile(path.join(__dirname, `../renderer/${MAIN_WINDOW_VITE_NAME}/index.html`))
}
// 打开开发者工具。
mainWindow.webContents.openDevTools()
}
// 当 Electron 完成初始化并准备好创建浏览器窗口时,将调用此方法。
// 某些 API 只能在此事件发生后使用。
app.on('ready', createWindow)
// 当所有窗口都关闭时退出,macOS 除外。
// 在 macOS 中,应用程序及其菜单栏通常会保持活动状态,直到用户使用 Cmd + Q 显式退出。
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
// 在 maxOS 上,当单击停靠图标并且没有其他窗口打开时,通常会在应用程序中重新创建一个窗口。
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
// 在此文件中,你可以包含应用程序特定主进程代码的其余部分。
// 你也可以将它们放在单独的文件中并在此处导入。
src/preload.js
// 有关如何使用预加载脚本的详细信息,请参阅 Electron 文档:
// https://www.electronjs.org/docs/latest/tutorial/process-model#preload-scripts
src/renderer.js
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.mount('#app')
forge.config.js
module.exports = {
packagerConfig: {
// 应用程序图标
icon: 'public/icon/Stella.ico',
},
rebuildConfig: {},
makers: [
{
name: '@electron-forge/maker-squirrel',
config: {
// 安装程序图标
setupIcon: 'public/icon/Stella.ico',
},
},
{
name: '@electron-forge/maker-zip',
// 打包方式对应的平台
platforms: ['darwin', 'linux'],
},
{
name: '@electron-forge/maker-deb',
config: {},
},
{
name: '@electron-forge/maker-rpm',
config: {},
},
],
plugins: [
{
name: '@electron-forge/plugin-vite',
config: {
// build 可以指定多个条目构建,可以是主进程、预加载脚本、辅助进程等。
// 如果你熟悉 Vite 的配置,它看起来真的很熟悉。
build: [
{
// entry 只是 config 对应文件中 build.lib.entry 的别名。
entry: 'src/main.js',
config: 'vite.main.config.mjs',
},
{
entry: 'src/preload.js',
config: 'vite.preload.config.mjs',
},
],
renderer: [
{
name: 'main_window',
config: 'vite.renderer.config.mjs',
},
],
},
},
],
}
index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>你好!世界!</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/renderer.js"></script>
</body>
</html>
package.json
{
"name": "my-vue-app",
"productName": "my-vue-app",
"version": "1.0.0",
"description": "My Electron application description",
"main": ".vite/build/main.js",
"scripts": {
"start": "electron-forge start",
"package": "electron-forge package",
"make": "electron-forge make",
"publish": "electron-forge publish",
"lint": "echo \"No linting configured\""
},
"keywords": [],
"author": {
"name": "xxx",
"email": "xxx@xx.xx"
},
"license": "MIT",
"devDependencies": {
"@electron-forge/cli": "^7.2.0",
"@electron-forge/maker-deb": "^7.2.0",
"@electron-forge/maker-rpm": "^7.2.0",
"@electron-forge/maker-squirrel": "^7.2.0",
"@electron-forge/maker-zip": "^7.2.0",
"@electron-forge/plugin-auto-unpack-natives": "^7.2.0",
"@electron-forge/plugin-vite": "^7.2.0",
"@vitejs/plugin-vue": "^5.0.4",
"electron": "28.2.3"
},
"dependencies": {
"electron-squirrel-startup": "^1.0.0",
"vue": "^3.4.19"
}
}
vite.main.config.mjs
import { defineConfig } from 'vite'
// https://vitejs.dev/config
export default defineConfig({
resolve: {
// 一些可以同时在 Web 和 Node.js 中运行的库,
// 例如 axios ,我们需要告诉 Vite 在 Node.js 上构建它们。
browserField: false,
conditions: ['node'],
mainFields: ['module', 'jsnext:main', 'jsnext'],
},
})
vite.preload.config.mjs
import { defineConfig } from 'vite'
// https://vitejs.dev/config
export default defineConfig({})
vite.renderer.config.mjs
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config
export default defineConfig({
plugins: [vue()]
})
项目示例
Electron + Vite + Vue
该项目包含 自定义窗口、系统托盘 等功能。关于 自动更新 等高级功能,作者还没有深入研究,感兴趣的小伙伴可以自行到官网进行学习。