直接回答:Electron 分成主进程和渲染进程,窗口、菜单、系统 API 归主进程,页面逻辑归渲染进程,两边通过 IPC 通信;国内安装慢是 electron 二进制走了境外地址,配好镜像变量即可。

主进程与渲染进程

关于renderer线程占用内存会越来越高的问题

1
window.electron.webFrame.clearCache()   //这可以清理下内存,特别是调试窗口关闭后

关于renderer线程崩溃,白屏

1
'render-process-gone'   // 监听这个事件,然后调用reload就可以在白屏的时候重启

关于preload中预加载

1
2
3
4
5
6
7
8
9
10
const { contextBridge, ipcRenderer } = require('electron');
const data = require(process.cwd() + '/config.json');
contextBridge.exposeInMainWorld('myAPI', {
readConfig: () => {
return data;
},
quit: () => {
ipcRenderer.send('quit');
},
});

通过这种方法将需要的接口暴露给前端程序,在页面中

1
2
window.myAPI.quit();
window.data = window.myAPI.readConfig()

可以通过这种方式调用,这样做是为了上下文隔离,为了安全

一些方便的操作在umijs中配置下发布路径

1
2
3
history: { type: 'hash' },
publicPath: './',
outputPath: '/electron/render',

关于菜单

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
const menu = new Menu();
menu.append(
new MenuItem({
label: '调试工具',
submenu: [
{
accelerator: 'F12',
role: '调试工具',
click: () => {
mainWindow.webContents.openDevTools();
},
},
{
accelerator: 'F10',
role: '全屏',
click: () => {
fullScreen = !fullScreen;
mainWindow.setFullScreen(fullScreen);
},
},
{
accelerator: 'F5',
role: '刷新',
click: () => {
mainWindow.reload();
},
},
],
}),
);

// const menu = Menu.buildFromTemplate([]);
Menu.setApplicationMenu(menu);

一个electron的package.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
{
"name": "electron",
"version": "1.0.0",
"description": "",
"main": "main.js",
"build": {
"appId": "com.relations.app",
"mac": {
"target":{"target":"dir","arch":"arm64"}
},
"win": {
"target": "zip",
"icon": "logo.ico"
},
"extraResources": {
"from": "./config.json", #一些配置文件需要复制到打包的文件里的时候
"to": "../"
}
},
"scripts": {
"electron": "electron .",
"buildElectron": "electron-builder --win --x64",
"buildElectron:mac": "electron-builder --mac --arm64"
},
"author": "",
"license": "ISC",
"devDependencies": {
"electron": "^16.0.0",
"electron-builder": "^22.13.1"
}
}

从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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
"use strict"

const builder = require("electron-builder")
const Platform = builder.Platform

// Let's get that intellisense working
/**
* @type {import('electron-builder').Configuration}
* @see https://www.electron.build/configuration/configuration
*/
const options = {
protocols: {
name: "Deeplink Example",
// Don't forget to set `MimeType: "x-scheme-handler/deeplink"` for `linux.desktop` entry!
schemes: [
"deeplink"
]
},

// "store” | “normal” | "maximum". - For testing builds, use 'store' to reduce build time significantly.
compression: "normal",
removePackageScripts: true,

afterSign: async (context) => {
// Mac releases require hardening+notarization: https://developer.apple.com/documentation/xcode/notarizing_macos_software_before_distribution
if (!isDebug && context.electronPlatformName === "darwin") {
await notarizeMac(context)
}
},
artifactBuildStarted: (context) => {
identifyLinuxPackage(context)
},
afterAllArtifactBuild: (buildResult) => {
return stampArtifacts(buildResult)
},
// force arch build if using electron-rebuild
beforeBuild: async (context) => {
const { appDir, electronVersion, arch } = context
await electronRebuild.rebuild({ buildPath: appDir, electronVersion, arch })
return false
},
nodeGypRebuild: false,
buildDependenciesFromSource: false,

directories: {
output: "dist/artifacts/local",
buildResources: "installer/resources"
},
files: [
"out"
],
extraFiles: [
{
from: "build/Release",
to: nodeAddonDir,
filter: "*.node"
}
],

win: {
target: 'nsis'
},
nsis: {
deleteAppDataOnUninstall: true,
include: "installer/win/nsis-installer.nsh"
},

mac: {
target: 'dmg',
hardenedRuntime: true,
gatekeeperAssess: true,
extendInfo: {
NSAppleEventsUsageDescription: 'Let me use Apple Events.',
NSCameraUsageDescription: 'Let me use the camera.',
NSScreenCaptureDescription: 'Let me take screenshots.',
}
},
dmg: {
background: "installer/mac/dmg-background.png",
iconSize: 100,
contents: [
{
x: 255,
y: 85,
type: "file"
},
{
x: 253,
y: 325,
type: "link",
path: "/Applications"
}
],
window: {
width: 500,
height: 500
}
},

linux: {
desktop: {
StartupNotify: "false",
Encoding: "UTF-8",
MimeType: "x-scheme-handler/deeplink"
},
target: ["AppImage", "rpm", "deb"]
},
deb: {
priority: "optional",
afterInstall:"installer/linux/after-install.tpl",
},
rpm: {
fpm: ["--before-install", "installer/linux/before-install.tpl"],
afterInstall:"installer/linux/after-install.tpl",
}
};

// Promise is returned
builder.build({
targets: Platform.MAC.createTarget(),
config: options
})
.then((result) => {
console.log(JSON.stringify(result))
})
.catch((error) => {
console.error(error)
})

electron-builder

一个electron上可以用的modbus库modbus-serial

窗口配置逐项说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
mainWindow = new BrowserWindow({
width: 1024,
height: 768,
frame: false, // 是否有边框,默认是有的
show: false, // 窗口是否显示,这里如果为false,需要在下面设置mainwindow.show()手动让显示
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
// sandbox: true,
// enableRemoteModule: true,
// session: ses,

},
//fullscreen: true,
});

mainWindow.loadFile('render/index.html'); // !本地地址
// mainWindow.loadURL('http://localhost:8000/')
// 当窗口已经渲染好当时候再让窗口显示,这样免得出现白屏闪动
mainWindow.once('ready-to-show', () => {
mainWindow.show();
});
}

BrowserWindow加载的时候可以加载本地html文件,也可以加载远程地址

在preload里面可以这么用

1
2
3
4
5
6
7
8
9
10
11
// 启用上下文隔离的情况下这么用
// preload.js
const { contextBridge, app } = require('electron');
const data = require(process.cwd()+ '/config.json');
contextBridge.exposeInMainWorld('myAPI', {
readConfig: () => {
return data;
},
});
// 渲染进程中
window.myAPI.readConfig() //通过这种方式去调用preload中注册的方法,将渲染进程和本机环境隔离开,避免被恶意攻击

下载慢的解决办法

1
2
3
4
5
6
npm config set registry https://registry.npm.taobao.org/
npm config set electron_mirror https://npm.taobao.org/mirrors/electron/
npm config set CHROMEDRIVER_CDNURL https://npm.taobao.org/mirrors/chromedriver
npm config set electron_builder_binaries_mirror https://npm.taobao.org/mirrors/electron-builder-binaries/
npm config set disturl https://npm.taobao.org/dist


这篇笔记整理自我自己的实践记录,如果做法有出入,或者你踩过别的坑,欢迎到留言板一起聊聊。

站内搜索

没有找到内容!