文章已阅读
 

以下内容是根据 官网 资料和自己实践整理(查阅资料)所得;

根据官网说明:Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。

创建第一个Electron应用程序

简介》

Electron应用程序是使用npm包建立的。Electron可执行文件应该安装在项目的devDependencies中,并且可以使用package.json文件中中的脚本在开发模式下运行。

可执行文件运行package.json的main属性中的JavaScript入口点。这个文件控制着Electron的主进程,它运行着Node.js的一个实例,负责应用的生命周期,显示本地接口,执行特权操作,以及管理渲染进程。

渲染进程(或简称渲染器)负责显示图形内容。您可以通过将网页指向一个web地址或一个本地HTML文件来将网页加载到渲染器中。渲染器的行为与普通网页非常相似,并且可以访问相同的web api。

学前需知》

通过将Chromium和Node.js嵌入到一个二进制文件中,Electron允许您使用一个JavaScript代码库创建在Windows、macOS和Linux上运行的跨平台应用程序。

Electron是一个原生的web应用包装层,运行在Node.js环境中,因此在进入学习之前需要熟悉Node和前端web开发基础知识:

Getting started with the Web (MDN Web Docs)

NodeJS官方入门指南

与其它桌面程序应用框架的对比》

同样是做桌面应用程序的框架,那么它和传统的Winform和WPF又有什么区别呢?

Winform:上手容易,技术老套,性能一般,常用组件库DevExpress,SunnyUI,适合对性能要求不高的项目

WPF:性能高,可以做炫酷的效果,上手进阶难,适合大型的桌面应用程序

Electron:对前端技术人员比较友好,相当于在网页上套了一层壳,可以打包成exe程序,只是打包后比较臃肿,性能堪忧,不过上手容易,方法都是封装好了的,根据官方可以快速构建一个桌面应用程序。

当然基于c++ 开发的QT框架也能做出漂亮的桌面应用程序。

所以这么看来Eelectron也是挺有优势的,因为是基于web开发来实现跨平台的桌面应用程序,对于如今广大的前端开发用户还是很友好的,当然其性能和对内存的处理以及打包文件的处理是不够好的。

开发工具》

这里我使用的是:Visual Studio Code

这个软件也是基于Electron开发出来的。

创建项目》

1
2
mkdir my-electron-app && cd my-electron-app
npm init

使用方式:
这里我是在E盘(你自己的项目存放位置)下的文件搜索框内容输入cmd,
这样打开命令提示符号终端窗口,然后输入

1
mkdir my-electron-app && cd my-electron-app

回车

这样就会在E盘下生成 my-electron-app 这个文件夹,并且指令进入此文件夹

接着使用指令

1
npm init

这样就是初始化创建了项目的配置文件

1
package.json

当然了如果使用了淘宝镜像,可以使用命令

1
cnpm init 

来替换

1
npm init

Electron的安装》

命令

1
npm install electron --save-dev

执行以上命令:在初始化包并安装Electron之后,package.json文件应该如下所示。同时文件夹下还生成了node_modules文件夹,其中包含Electron可执行文件,以及一个包锁:.package-lock.json来指定要安装的确切依赖版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"name": "my-electron-app",
"version": "1.0.0",
"description": "electron progroam",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "zl",
"license": "ISC",
"devDependencies": {
"electron": "^20.0.1"
}
}

在以上文件(package.json)中的main对应的脚本文件(这里是main.js)
它是Electron应用程序的入口。这个脚本控制主进程,它运行在Node.js环境中,负责控制应用的生命周期,显示本机接口,执行特权操作,以及管理渲染进程(后面会详细介绍)。
这里的main.js是我们在创建应用的时候自己命名的,但是框架并没有为我们生成这个js文件,所以我们需要在根目录下自己去手动生成,以此来保证配置正确运行。这里我们将main.js中的内容设置简单点:

1
console.log('hello Electron!');

程序启动配置》

由于Electron的主进程是在Node.js中运行的,所以您可以使用Electron命令执行任意Node.js代码(甚至可以将其用作REPL)。
要执行这个脚本,就需要需要添加“electron .”到package.json的scripts字段中的start指令中。这个指令将告诉Electron可执行文件在当前目录中查找主脚本,并在dev模式中运行它。这样package.json内容如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"name": "my-electron-app",
"version": "1.0.0",
"description": "electron progroam",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start":"electron ."
},
"author": "zl",
"license": "ISC",
"devDependencies": {
"electron": "^20.0.1"
}
}

配置完start指令后,通过在终端(cmd)运行指令 npm run start便会在终端打印出“hello Electron!”。
当然这只是在Electron中执行了打印文字的脚本,接下来将学习如何使用HTML创建用户界面并将其加载到本地窗口中。
上面我们实现了通过在终端运行Electron指令–执行入口文件main.js

功能:打印文字;

接下来我们将学习如何在BrowserWindow中加载网页。

根据官网介绍:

In Electron, each window displays a web page that can be loaded either from a local HTML file or a remote web address.
在Electron中,每个窗口都显示一个可以从本地HTML文件或远程web地址加载的网页。

也就是Electron应用程序窗口可以显示本项目中的.html文件,也可以通过加载网站网络地址来实现网页的呈现。
如果是加载网站的url来实现网页的呈现,这种方式就相当于我们把网站开发好了,发布到外网上。然后在Electron中加载进来就可以了,相当于给网站外加了个一个浏览器的壳,这样对前端开发人员来说是相当友好滴。

接下来将介绍如何在Electron框架下的BrowserWindow中加载本地html文件以及已发布网站地址。

1)在BrowserWindow中加载本地(本项目)html文件

我们在根目录下创建一个名为index.html的文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'"
/>
<meta
http-equiv="X-Content-Security-Policy"
content="default-src 'self'; script-src 'self'"
/>
<title>Hello from Electron renderer!</title>
</head>
<body>
<h1>Hello from Electron renderer!</h1>
<p>??</p>
</body>
</html>

那么我们如何将这个网页加载到Electron的浏览器窗口(BrowserWindow)中去呢?
前面我们已经了解到了,package.json配置文件中的main对应的是整个Electron程序的入口文件(这里是:main.js)。
这样我们需要将main.js中的内容修改为以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const {
app,
BrowserWindow
} = require('electron')
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
})
win.loadFile('index.html')
}
app.whenReady().then(() => {
createWindow()
})

让我们看看以上配置内容的语义。

1
2
3
4
const {
app,
BrowserWindow
} = require('electron')

以上配置用CommonJS模块语法导入了两个Electron模块:

app:控制整个应用程序事件的声明周期

BrowserWindow:创建和管理应用程序的窗口

这里我们可能已经注意到模块名称的大小写并不是使用统一的规则,这里面是有它自己的规则的,根据官网说明:

Electron在这里遵循典型的JavaScript约定,其中PascalCase模块是可实例化的类构造函数(如BrowserWindow, Tray, Notification),而camelCase模块是不可实例化的(如app, ipcreender, webContents)。

需要注意的是:目前Electron不直接支持ECMAScript模块(即使用import来加载模块)。

1
2
3
4
5
6
7
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
})
win.loadFile('index.html')
}

以上配置表示:通过函数createWindow()加载你的网页到一个新的BrowserWindow实例;
也就是说窗口BrowserWindow可以被我们重写的,这样我们可以控制它的大小、显示的位置、是否显示自带的辅助功能菜单(File、Edit、View、Window、Help)以及是否显示最小化,最大化和关闭图标等功能。

1
2
3
app.whenReady().then(() => {
createWindow()
})

以上配置表示:应用程序执行时候就调用我们定义的函数createWindow()(重写BrowserWindow)
Electron的许多核心模块都是Node.js事件触发器,它们遵循Node的异步事件驱动架构。app模块就是其中一个发射器。

在Electron中,BrowserWindows只能在app模块的ready事件触发后创建。
你可以通过使用app.whenReady() API以及等这个事件的promise执行完后来回调createWindow()

2)在BrowserWindow中加载网站网络URL来实现网页的呈现

在以上内容的基础上,我们只需要将配置:

1
win.loadFile('index.html')

修改为

1
win.loadURL('https://www.romanticlife.top')

这样就可以在BrowserWindow调用已发布的网站(本博客)
现在我们执行指令

1
npm run start

此时我们看到index.html文件加载到窗口(BrowserWindow)中去了。
至此,Electron应用程序是已经能够正常的运行起来了,那么我们如如何去管理应用程序的窗口生命周期喃?

管理应用程序的声明周期》

Electron应用程序在窗口中显示的每个网页将运行在一个单独的进程中,称为渲染进程(或简称为渲染器)。

这个渲染过程与通用网页的渲染过程是一致的,即渲染过程可以访问与典型前端web开发相同的JavaScript api和工具,例如使用webpack来捆绑和缩减代码,或者使用React来构建用户界面…

应用程序窗口在每个操作系统上的行为都不同。比起默认地强制执行这些约定,Electron给你在应用程序代码中实现它们的选择,如果你希望遵循它们。你可以通过监听由应用程序和BrowserWindow模块发出的事件来实现基本的窗口约定。

检查Node的进程。平台变量可以帮助您在特定平台上有条件地运行代码。

注意

Electron只能在三种可能的平台上运行:win32 (Windows)、linux (linux)和darwin (macOS)。

关闭所有窗口时退出应用 (Windows & Linux)》

注意这里只是针对:window和Linux系统,macOS系统不适用。

在Windows和Linux上,关闭所有窗口通常会完全退出应用程序。如果要在Electron应用程序中实现这个模式,需要监听app模块的window-all-closed事件,并调用app.quit()来退出你的应用程序

1
2
3
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})

这样我们就是实现了一个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
45
46
47
48
49
50
51
52
53
54
55
56
package.json
{
"name": "my-electron-app",
"version": "1.0.0",
"description": "electron progroam",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start":"electron ."
},
"author": "zl",
"license": "ISC",
"devDependencies": {
"electron": "^20.0.1"
}
}
main.js
const {
app,
BrowserWindow
} = require('electron')
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
})
win.loadFile('index.html')
}

app.whenReady().then(() => {
createWindow()
})

app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
index.html
<!DOCTYPE html>
<html>

<head>
<meta charset="UTF-8" />
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'" />
<meta http-equiv="X-Content-Security-Policy" content="default-src 'self'; script-src 'self'" />
<title>Hello from Electron renderer!</title>
</head>

<body>
<h1>Hello from Electron renderer!</h1>
<p>??</p>
</body>

</html>

项目调试

如果你想在VS Code工具中调试Electron应用程序,则需要将VS Code附加到主进程和渲染进程。
以下是要运行的示例配置:

在你的项目下新建一个.vscode文件夹,并在其下创建一个launch.json配置文件:

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
{
"version": "0.2.0",
"compounds": [
{
"name": "Main + renderer",
"configurations": ["Main", "Renderer"],
"stopAll": true
}
],
"configurations": [
{
"name": "Renderer",
"port": 9222,
"request": "attach",
"type": "pwa-chrome",
"webRoot": "${workspaceFolder}"
},
{
"name": "Main",
"type": "pwa-node",
"request": "launch",
"cwd": "${workspaceFolder}",
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron",
"windows": {
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron.cmd"
},
"args": [".", "--remote-debugging-port=9222"],
"outputCapture": "std",
"console": "integratedTerminal"
}
]
}

做了以上工作后,当你选择侧边栏的“运行和调试”时,会出现“Main + renderer”选项,这将允许你设置断点并检查主进程和渲染进程中的所有变量。

在以上launch.json文件中有3个配置项:

1)Main用于启动主进程,并开放9222端口用于远程调试(–remote-debugging-port=9222)。这是我们将用于监听Renderer调试器的端口。因为主进程是一个Node.js进程,类型被设置为pwa-node (pwa-是用来告诉VS Code使用最新的JavaScript调试器的一个前缀)。
2)Renderer用于调试渲染器进程。由于这个进程(Renderer)是由主进程创建的,所以我们必须“附加”到主进程上(“request”:“attach”),而不是创建一个新的进程。渲染器进程是一个web进程,所以不得不使用pwa-chrome作为调试器。
3)Main + renderer是一个复合任务,可以同时执行前面的任务。

因为我们是在Renderer中附加一个进程,所以有可能你的代码的前几行会被跳过,因为调试器在它们被执行之前没有足够的时间进行连接。可以通过刷新页面或在开发模式执行代码之前设置settimeout来解决这个问题。

【知识延申】》如何给Chrome浏览器开启远程调试的功能?

。找到Chrome浏览器的安装地址(在Chrome浏览器的搜索栏输入:chrome://version 出现页面信息中的“可执行文件路径”项即是当前电脑中Chrome浏览器的安装地址);
。关闭所有打开的Chrome浏览器
。在地址栏输入cmd,打开命令终端
。在命令终端中输入:chrome.exe –remote-debugging-port=9222

按照以上操作后便会自动打开一个网页:http://127.0.0.1:9222/json/version
页面中的webSocketDebuggerUrl后面的地址,这就是我们远程链接的地址;测试的过程中,可能会发现标签页越开越多。只要至少保留一个标签页不关闭,那么这个浏览器窗口就可以一直使用。
当然如果你想在调试方面有更深入的了解,下面的指南提供了更多的信息:

Application Debugging

DevTools Extensions

预加载脚本:preload.js

接下来将了解什么是预加载脚本,以及如何使用预加载脚本安全地将私有api公开到渲染进程中以及如何使用Electron的进程间通信(IPC)模块在主进程和渲染进程之间通信。

什么是预加载脚本?

预加载脚本中的代码在网页加载到浏览器窗口之前运行。它可以访问DOM API和Node.js环境,通常通过contextBridge API向渲染器暴露私有API。

因为主进程和渲染进程的职责有很大不同,Electron应用程序经常使用预加载脚本建立进程间通信(IPC)接口,在两种进程之间传递任意消息。

Electron的主进程是一个具有完全操作系统访问权限的Node.js环境。在Electron模块之上,你还可以访问Node.js内置模块,以及任何通过npm安装的包。另一方面,由于安全原因,渲染进程运行网页时默认不运行Node.js。

为了将Electron的不同过程类型连接在一起,我们需要使用一种称为预加载的特殊脚本。

接下来了解使用预加载脚本增强渲染器。

BrowserWindow的预加载脚本运行在可以访问HTML DOM和Node.js环境的上下文中。在渲染器加载页面之前会注入预加载脚本,类似于Chrome扩展的内容脚本。若要向渲染器添加需要特权访问的特性,可以通过contextBridge API定义全局对象。

为了演示这个概念,我们创建一个预加载脚本,实现将应用程序的Chrome、Node和Electron版本暴露到渲染器中。

新建preload.js脚本,用于暴露Electron进程的选定属性。在Versions全局变量中向渲染器进程添加Versions对象。内容如下:

1
2
3
4
5
6
7
8
const { contextBridge } = require('electron')

contextBridge.exposeInMainWorld('versions', {
node: () => process.versions.node,
chrome: () => process.versions.chrome,
electron: () => process.versions.electron,
// we can also expose variables, not just functions
})

要将这个脚本附加到你的渲染器进程,需要将它的路径传递给BrowserWindow构造函数中的webPreferences.preload项:

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
/*main.js */
const {
app,
BrowserWindow
} = require('electron')
const path = require('path')
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
},
})
win.loadFile('index.html')
}

app.whenReady().then(() => {
createWindow()
})

app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});

在以上内容中我们用到了两个Node.js的知识点:

1)__dirname 字符串指向当前正在执行的脚本的路径(本例中即为项目的根文件夹)。

2)path. join 接口将多个路径拼接在一起,组成一个跨所有平台的组合路径字符串。

此时,渲染器可以访问全局versions,接着让我们在窗口中显示该版本信息。这个变量可以通过window.versions或versions访问。

新建一个renderer.js脚本,用于通过 document.getElementById DOM API实现将 id为info的HTML元素的文本信息替换为版本信息:

1
2
3
/*renderer.js*/
const information = document.getElementById('info')
information.innerText = `This app is using Chrome (v${versions.chrome()}), Node.js (v${versions.node()}), and Electron (v${versions.electron()})`

然后修改index.html,添加一个id属性为info的新元素,并引入renderer.js脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'"
/>
<meta
http-equiv="X-Content-Security-Policy"
content="default-src 'self'; script-src 'self'"
/>
<title>Hello from Electron renderer!</title>
</head>
<body>
<h1>Hello from Electron renderer!</h1>
<p>??</p>
<p id="info"></p>
</body>
<script src="./renderer.js"></script>
</html>

完成以上步骤后,运行程序我们可以看到窗口显示出Chorm、Node.js、Electron的版本信息。

进程间通信

正如上面所提到的那样,Electron的main和renderer进程职责不同且不可互换。这意味着不能从渲染进程直接访问Node.js api,也不能从主进程访问HTML文档对象模型(DOM)。

解决这个问题的方法是使用Electron的ipcMain和ipcrederer模块进行进程间通信(IPC)。如需从你的网页向主进程发送消息,你可以用ipcMain.handle句柄建立一个主进程,然后在预加载脚本中暴露一个调用ipcRenderer.invoke的函数去触发这个句柄。

为了演示这个观点,我们将在渲染器中添加一个名为ping()的全局函数,该函数将从主进程返回一个字符串。

首先,在预加载脚本中配置调用:

1
2
3
4
5
6
7
8
9
10
11
12
const {
contextBridge,
ipcRenderer
} = require('electron')

contextBridge.exposeInMainWorld('versions', {
node: () => process.versions.node,
chrome: () => process.versions.chrome,
electron: () => process.versions.electron,
ping: () => ipcRenderer.invoke('ping'),
// we can also expose variables, not just functions
})

IPC安全机制》

请注意,我们为何将ipcRenderer.invoke(‘ping’) 调用封装在一个帮助函数中,而不是直接通过上下文桥接暴露ipcRenderer模块的。你绝对不想通过preload直接暴露整个ipcRenderer模块。这将使渲染器能够向主进程发送任意IPC消息,并将为恶意代码提供有力的攻击载体。

然后,在主进程中设置handle 侦听器,此操作需要在加载HTML文件之前执行,以确保在渲染器进程发出invoke调用之前handle 侦听器已准备就绪:

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
/*main.js */
const {
app,
ipcMain,
BrowserWindow
} = require('electron')
const path = require('path')
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
},
})
ipcMain.handle('ping', () => 'pong')
win.loadFile('index.html')
}

app.whenReady().then(() => {
createWindow()
})

app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});

设置好发送方和接收方之后,现在就可以通过刚才定义的“ping”通道从渲染器向主进程发送消息了。

1
2
3
4
5
6
7
8
9
10
/*renderer.js*/
const information = document.getElementById('info')
information.innerText = `This app is using Chrome (v${versions.chrome()}), Node.js (v${versions.node()}), and Electron (v${versions.electron()})`

const func = async () => {
const response = await window.versions.ping()
console.log(response) // prints out 'pong'
}

func()

若要对ipcRenderer 和ipcMain模块更深入理解,查看完整的Inter-Process Communication指南。

接下来将了解为应用添加更多功能的环境,又如何将应用分发给用户。

添加功能

即增加应用程序的复杂性。

如果您一直按照本文进行操作,至此,您应该拥有一个具有静态用户界面的功能性Electron应用程序。从现在开始,你可以从两个大的方向来提升你的应用:

1)增加渲染进程的web应用程序代码的复杂性

2)使操作系统和Node.js的深度集成

理解这两个宽泛概念之间的区别是很重要的。

对于第一点,Electron对特殊环境是非必要的。在Electron中构建一个漂亮的待办事项列表的应用程序只是将你的Electron BrowserWindow指向一个漂亮的待办事项列表web应用程序。最终,你正在使用与在web上相同的工具(HTML、CSS、JavaScript)构建你的渲染器UI。因此,Electron的文档不会深入讨论如何使用标准的web工具。

另一方面,Electron还提供了一组丰富的工具,允许您与桌面环境集成,从创建托盘图标到为显示本地菜单添加全局快捷方式。它还在主进程中为您提供了Node.js环境的所有功能。这一功能集将Electron应用程序与在浏览器选项卡中运行网站分开,并且是Electron文档的重点。

Electron的文档中有许多教程,可以帮助您了解更高级的话题和更深入的操作系统集成。要开始使用,
请查看How-To Examples文档。

接着继续了解如何使Electron应用程序让最终用户使用?

为此我们将学习使用Electron Forge打包和分发应用程序的基础知识。

应用程序打包

Electron没有任何打包和分发的工具捆绑到其核心模块中。一旦你有了一个在开发模式下工作的Electron应用程序,你需要使用其他工具来创建一个打包的应用程序,你可以分发给你的用户(也称为分发版)。分发文件可以是安装程序(如Windows上的MSI),也可以是可移植的可执行文件(如macOS上的.app)。

打包项目》

将 Electron Forge 添加到您应用的开发依赖中
electron-forge 相当于 的一个脚手架,可以让我们更方便的创建、运行、打包 项目

注意:electron-forge打包时是需要安装git的;
因为它在打包时会检测系统有没有装git,没有是打不了包的 。

并使用其”import”命令设置 Forge 的脚手架

1
2
3
cnpm install @electron-forge/cli -g

npx electron-forge import

以上两条命令执行成功后会在项目中package.json文件scripts节点中自动新增以下内容:

1
2
3
"package": "electron-forge package",

"make": "electron-forge make"

执行

1
npm run package

会在根目录下生成可执行程序.exe文件夹out。

执行

1
npm run make

包含以下2个步骤:

1)首先它将引用线下运行electronic -forge包,将您的应用程序代码与Electron二进制文件捆绑在一起。打包的代码将生成到一个文件夹中。

2)然后它将使用这个打包的app文件夹为每个配置的制造者创建一个单独的分发版。npm run make命令执行后,会在根目录下生成一个out文件夹,其中包含分发版和一个包含打包的应用程序代码(.exe)的文件夹。

这样,out/make文件夹中的分发版应该可以启动了

至此您已经创建了第一个捆绑的Electron应用程序。

以上我们已经成功生成了可执行文件,如何修改它exe可执行程序的图标、程序名称(xxx.exex)。。。???

配置程序图标和名称等》

这是可以在打包脚本中去配置的:

1
"package":"electron-packager . appName --platform=win32 --arch=x64 --icon=favicon.ico --out=./out --asar --app-version=1.0.1 --overwrite --ignore=node_modules",

.appName

表示生成的exe可执行文件的名称是appName,即:appName.exe

–icon=favicon.ico

设置可执行文件的图标是favicon.ico,这个图标文件是我们已手动放在根目录下

–out=./out

指定打包文件输出的文件夹位置,当前指定的为项目目录下的out文件夹

–asar

该参数可以不加(一般需要加上),如果加上,打包之后应用的源码会以.asar格式存在;否则会以文件夹app形式存在,app中呈现源码

–app-version=1.0.1

设置项目程序的版本号

–overwrite

表示此次打包会覆盖上次打包的内容

–ignore=node_modules

指定打包时忽略目录:node_modules

发布与更新

如果您一直按照本教程的流程学习,这是本教程的最后一步!在这小结,你将发布你的应用到

GitHub releases

上,并将自动更新集成到你的应用代码中。

使用update.electronjs.org

Electron的维护者在 https://update.electronjs.org/ 上为开源应用程序提供免费的自动更新服务。它的要求是:

1)应用运行在macOS或Windows上

2)应用程序有一个公共的GitHub库

3)构建版本发布到GitHub releases

4)构建是代码签名的(code signed

发布GitHub release

Electron Forge拥有 Publisher 插件,可以自动将打包的应用程序分发到各种来源。在本教程中,我们将使用GitHub Publisher,它将允许我们将我们的代码发布到GitHub上。

生成个人访问令牌

Forge不能在未经允许的情况下发布到GitHub上的任何存储库。你需要传入一个经过验证的令牌,让Forge能够访问你的GitHub发行版。最简单的方法是使用 public_repo作用域 create a new personal access token (PAT),它提供对公共存储库的写访问。一定要保密这个标志。

设置GitHub发布者

安装模块

Forge的 GitHub Publisher 是一个需要安装在你的项目的devDependencies中的插件:

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

1
yarn add --dev @electron-forge/publisher-github

在Forge中配置发布者

一旦您安装了它,您需要在您的Forge配置中设置它。一个完整的选项列表记录在Forge的 PublisherGitHubConfig API文档中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*package.json*/
{
//...
"config": {
"forge": {
"publishers": [
{
"name": "@electron-forge/publisher-github",
"config": {
"repository": {
"owner": "github-user-name",
"name": "github-repo-name"
},
"prerelease": false,
"draft": true
}
}
]
}
}
//...
}

设置身份验证令牌

您还需要让发布服务器知道您的身份验证令牌。默认情况下,它将使用存储在 GITHUB_TOKEN环境变量中的值。

运行发布指令

把Forge的 publish command 添加到你的npm脚本中:

1
2
3
4
5
6
7
8
9
10
11
12
13
/*package.json*/
//...
"scripts": {
"start": "electron-forge start",
"package": "electron-forge package",
"make": "electron-forge make",
"publish": "electron-forge publish"
},
//...
```
这个命令将运行你配置的makers,并将输出分发版发布到新的GitHub版本:
```bash
npm run publish

1
yarn run publish

默认情况下,这只会为您的主机操作系统和体系结构发布一个发行版。你可以通过传递–arch 标志到你的Forge命令来发布不同的架构。

这个版本的名称将对应于项目文件package.json中的version 字段。

在GitHub Actions中发布

在本地发布是很痛苦的,特别是因为你只能为你的主机操作系统创建分发版(也就是说,你不能从macOS发布windows.exe文件)。

一个解决方案是通过自动化工作流发布你的应用程序,比如 GitHub Actions,它可以在Ubuntu、macOS和Windows上运行云中的任务。这正是 Electron Fiddle 所采用的方法。你可以参考Fiddle
Build and Release pipeline 以及 Forge configuration 来了解更多细节。

测试更新程序代码

现在我们有了一个通过GitHub releases的功能发布系统,我们现在需要告诉我们的Electron应用程序在新发布的时候下载更新。Electron应用程序通过 autoUpdater 模块实现这一功能,该模块从更新服务器提要读取数据,以检查是否有新版本可供下载。

update.electronjs.org服务提供了一个与更新程序兼容的提要。例如,Electron Fiddle v0.28.0将在https://update.electronjs.org/electron/fiddle/darwin/v0.28.0 上检查端点,以查看是否有更新的GitHub版本可用。服务提供了一个与更新程序兼容的提要。例如,Electron Fiddle v0.28.0将在https://update.electronjs.org/electron/fiddle/darwin/v0.28.0 上检查端点,以查看是否有更新的GitHub版本可用。

在你的版本发布到GitHub后,update.electronjs.org服务应该可以为你的应用程序工作。剩下的唯一步骤是使用autoUpdater 模块配置提要。

为了使这个过程更容易,Electron团队维护 update-electron-app 模块,该模块在一个函数调用中为update.electronjs.org设置autoUpdater 样板文件——不需要配置。此模块将搜索update.electronjs.org feed,此与项目 package.json文件中”repository”字段匹配。

首先,将安装作为运行时依赖项的模块:

1
npm install update-electron-app

1
yarn add update-electron-app

然后,导入模块并在主进程中立即调用它:

1
2
/*main.js*/
require('update-electron-app')()

这样,一旦打包应用,它会为你发布的每一个新的GitHub版本实现自我更新。

在本小结中,我们配置了Electron Forge的GitHub发布者上传你的应用程序的分发到GitHub发行版。由于分发版不能总是在平台之间生成,如果您无法访问机器,我们建议在持续集成管道中设置您的构建和发布流程。

Electron应用程序可以通过将autoUpdater模块指向更新服务器feed进行自我更新。update.electronjs.org是Electron为GitHub上发布的开源应用提供的一个免费更新服务器。配置您的Electron应用程序来使用该服务就像安装和导入update-electron-app模块一样简单。

如果您的应用程序不符合update.electronjs.org的条件,您应该部署自己的更新服务器,并自己配置autoUpdater模块。

问题集锦》

1)命令cnpm install electron -g 是全局安装,用于在第一次安装后出现‘electron’不被识别的情况,安装成功了,使用:electron -v命令可以查看版本号。

当然了使用这个命令前需要添加淘宝镜像;具体可参照前面创建Vue项目里的操作方法,也可自行百度。

这里我在使用这个命令时出现了以下错误:

Error: EPERM: operation not permitted, mkdir ‘D:\softprogram\nodejs\node_modules\electron_tmp’
原因是:node权限问题;

解决办法:这里我们进入:D:\softprogram\nodejs》右键》属性》安全》点击“编辑”》选中“Users”》勾选权限框 “允许”栏中的所有权限》应用》确定

再执行命令:cnpm install electron -g,即可成功安装。

相关资料

1、Electron构建跨平台应用

浏览 |

© 2023 南疆 with help from Hexo and Twitter Bootstrap. Theme by Freemind.

container-narrow -->