Electron 学习笔记

介绍

什么是 Electron

其实就是一个转换器, 只要我们可以写一个网站, 就可以创建一个桌面应用程序. Electron 使用的是 JS, HTML 和 CSS 等技术创建原生程序的框架.

为什么选择 Electron

因为 Electron 可以使用纯 JS 来调用原生 APIs, 创建桌面应用. 同时 Electron 的社区比较活跃, bug 也比较少, 文档相对简洁.

另外, NodeJs 的所有的内置模块都可以在 Electron 中使用. 可以说非常的通用.

快速上手

安装 Electron

首先, 初始化一个项目, 在一个新的文件夹中进行初始化.

1
npm init

随后安装 electron.

1
cnpm i electron -S

随后, 我们需要配置一个命令用来运行 electron. 配置后, json 文件如下.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"name": "electron-study",
"version": "1.0.0",
"description": "",
"license": "ISC",
"author": "",
"type": "commonjs",
"main": "main.js",
"scripts": {
"run": "electron ."
},
"dependencies": {
"electron": "^37.1.0"
}
}

实现入口

创建对应的 main.js 文件. electron 需要使用 require 来进行导入. 其中有一个 app:

1
2
3
4
// 这里会有一个app对象, 用来控制程序的生命周期
const { app } = require("electron");

app.on("ready", () => { });

直接运行程序, 什么都不会发生. 这是因为我们这是一个窗口, 需要告诉他宽和高, 以及一个窗口. 窗口就是 BrowserWindow 了. 再次导入进行实例化.

1
2
3
4
5
6
7
8
9
10
// 这里会有一个app对象, 用来控制程序的生命周期
const { app, BrowserWindow } = require("electron");

app.on("ready", () => {
// 实例化窗口
new BrowserWindow({
width: 640,
height: 480,
});
});

运行后, 已经看到我们的应用程序了!

有了窗口, 自然需要显示我们想要的内容. 我们记录这个主窗口对象, 并且读取一个文件. 为了读取文件, 先创建一个文件. 这里在 src 目录中创建一个 index.html.

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<h1>Hello Electron</h1>
</body>
</html>

随后, 在 main.js 中进行导入.

1
2
3
4
5
6
7
8
9
10
11
12
13
// 这里会有一个app对象, 用来控制程序的生命周期
const { app, BrowserWindow } = require("electron");

app.on("ready", () => {
// 实例化窗口
const mainWindow = new BrowserWindow({
width: 640,
height: 480,
});

// 加载文件
mainWindow.loadFile("./src/index.html");
});

再次运行, 页面显示出来了!

配置自动刷新

刚才, 我们每次修改后都需要手动重新运行程序, 这非常的不友好. 所以我们可以使用一个工具来实现自动更新.

1
cnpm install --save-dev electron-reloader

安装后, 添加两行代码即可实现热加载.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 这里会有一个app对象, 用来控制程序的生命周期
const { app, BrowserWindow } = require("electron");

// 热加载
const reloader = require("electron-reloader");
reloader(module);

// 监听 初始化完成的生命周期
app.on("ready", () => {
// 实例化窗口
const mainWindow = new BrowserWindow({
width: 640,
height: 480,
});

// 加载文件
mainWindow.loadFile("./src/index.html");
});

主进程 & 渲染进程

介绍

简单说, Electron 运行的 main.js 就是我们的主进程. 主进程中运行的脚本通过创建 Web 页面来展示用户页面. 一个 Electron 有且只有一个主进程. 另外, 别的页面就是渲染进程了.

同时, 主进程中 console 的内容, 是在控制台中的. 渲染进程则是在程序的控制台中进行查看. 可以通过 Ctrl + Shift + I 来打开控制台.

通信 TODO

自定义原生菜单

原生菜单, 就是我们看到的这个菜单:

基本使用

我们首先需要引入 Menu 模块进行修改. 另外, Menu 需要一个菜单配置对象来进行配置. 菜单需要一个模板.

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
// 这里会有一个app对象, 用来控制程序的生命周期
const { app, BrowserWindow, Menu } = require("electron");

// 热加载
const reloader = require("electron-reloader");
reloader(module);

const initMenu = () => {
// 初始化一个模板对象
const template = [
{
label: "文件",
},
{
label: "关于我们",
},
];

// 编译菜单模板
const newMenu = Menu.buildFromTemplate(template);

// 设置菜单
Menu.setApplicationMenu(newMenu);
};

// 监听 初始化完成的生命周期
app.on("ready", () => {
// 实例化窗口
const mainWindow = new BrowserWindow({
width: 640,
height: 480,
});

// 加载文件
mainWindow.loadFile("./src/index.html");

// 初始化菜单
initMenu();
});

|162

可以看到, 基本的菜单已经进行了重构了.

定义子菜单

通过 submenu 配置子菜单部分.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const template = [
{
label: "文件",
// 配置子菜单
submenu: [
{
label: "新建",
},
{
label: "退出",
},
],
},
{
label: "关于我们",
},
];

|84

添加点击事件

直接配置 click 属性即可. 属性是一个函数, 比如创建一个新的窗口.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const template = [
{
label: "文件",
// 配置子菜单
submenu: [
{
label: "新建",
click: () => {
new BrowserWindow({
width: 100,
height: 100,
});
},
},
{
label: "退出",
},
],
},
{
label: "关于我们",
},
];

|450

可以看到可以正常的执行指令.

自定义菜单

首先, 我们需要禁用这个菜单. 只需要在创建主窗口的时候, 配置 frame 为 false 即可. 这代表创建了一个无边框窗口.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 这里会有一个app对象, 用来控制程序的生命周期
const { app, BrowserWindow } = require("electron");

// 热加载
const reloader = require("electron-reloader");
reloader(module);

// 监听 初始化完成的生命周期
app.on("ready", () => {
// 实例化窗口
const mainWindow = new BrowserWindow({
width: 640,
height: 480,
frame: false,
});

// 加载文件
mainWindow.loadFile("./src/index.html");
});

运行后可以看到确实啥都没有:

这里我们自己来实现一个简单的顶部菜单:

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
}
.header {
display: flex;
width: 100%;
height: 30px;
background-color: dodgerblue;
/* 为了实现能够拖动 添加一个 */
-webkit-app-region: drag;
}
</style>
</head>
<body>
<!-- 实现顶部菜单 -->
<div class="header"></div>
<h1>Hello Electron</h1>
</body>
</html>

至此, 就实现了自定义的菜单了.

结合框架开发

普通使用

比如说, 我想结合 Vue 进行开发. 首先, 我们创建一个 Vue 的项目.

1
yarn create vite

创建项目后, 我们需要安装 Electron 的包, 进而使用 Electron.

1
yarn add electron

另外, 配置一下 electron 的启动项目以及入口文件.

1
2
3
4
5
6
{
"main": "main.js",
"scripts": {
"electron": "electron ."
}
}

创建对应的入口文件. 这里加载的是 Vue 启动后的网页, 不是一个静态页面了.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 注意, 这里根据项目类型而改变 Vue的是module, 所以使用import, 如果是commonjs则使用require
import { app, BrowserWindow } from "electron";

const createWindow = () => {
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
});

mainWindow.loadURL("http://localhost:11123");
};

app.on("ready", () => {
createWindow();
});

这里的端口可以根据使用的脚手架进行配置, 我这里使用的是 Vite, 直接修改 config 即可.

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

export default defineConfig({
plugins: [vue()],
server: {
host: "0.0.0.0",
port: 11123,
},
});

随后, 我们先启动 Vue 项目, 再启动 electron 就可以开始正常开发了.

1
2
3
4
5
# 启动项目
yarn dev

# 启动electron
yarn electron

效果还是很不错的.

使用框架

我们一般使用的都是 Vite 框架, 这里有两个, 一个是直接准备好的项目模板

1
2
3
4
url: https://vite.electron.js.cn/
title: "Electron⚡️Vite | Electron⚡️Vite 中文"
host: vite.electron.js.cn
favicon: https://vite.electron.js.cn/electron-vite.svg

另一种就是进行单独的安装操作.

1
2
3
4
5
url: https://cn.electron-vite.org/
title: "electron-vite | 下一代 Electron 开发构建工具"
description: "Next generation Electron build tooling based on Vite."
host: cn.electron-vite.org
favicon: https://cn.electron-vite.org/favicon.svg

我使用第一个用的比较多, 一行命令就搞定几乎所有东西, 不需要手动进行配置.

1
npm create electron-vite@latest

然后直接 npm run dev, 就可以看到效果了, 比自己配置方便太多了.