demo仓库

1. 安装

npm init
修改package.json为以下内容

json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// package.json
{
"name": "electron-demo",
"version": "1.0.0",
"description": "demo",
"main": "main.js",
"scripts": {
"start": "electron .",
"build": "electron-builder",
"build:icon": "electron-icon-builder --input=./public/icon.png --output=release --flatten"
},
"author": {
"name": "cai",
"email": "your-email.com",
},
"license": "ISC"
}

安装electron、打包工具electron-builder和图标打包工具electron-icon-builder

npm install -D electron electron-builder electron-icon-builder

配置打包内容

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
33
34
35
36
37
// package.json
{
"build": {
"appId": "com.kissshot.electrondemo",
"productName": "ElectronDemo",
"directories": {
"output": "dist"
},
"linux": {
"icon": "./release/icons",
"target": "deb",
"category": "Utility"
},
"deb": {
"afterInstall": "./entries/install.sh"
},
"extraFiles": [
{
"from": "entries",
"to": "entries"
}
],
"win": {
"icon": "./release/icons",
"target": ["nsis","zip"]
},
"nsis": {
"oneClick": false,
"perMachine": false,
"allowElevation": true,
"allowToChangeInstallationDirectory": true,
"createDesktopShortcut": true,
"createStartMenuShortcut": false,
"deleteAppDataOnUninstall": true
}
}
}

2. 基本配置

2.1 打包准备

  • 图标
    根据package.json中script的配置,新建文件夹public放入图片icon.png
  • linux
    新建文件夹entries编写脚本文件install.sh。在linux中,electron在沙箱中运行,安装时给沙箱更改所有者并设置权限
    shell
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #! /bin/sh
    # 设置 chrome-sandbox 的所有者为 root 并设置正确的权限
    # 确保使用正确的路径到您的 chrome-sandbox 文件
    chromeSandboxPath="/opt/ElectronDemo/chrome-sandbox"
    # 检查 chrome-sandbox 文件是否存在
    if [ -f "$chromeSandboxPath" ]; then
    # 更改所有者为 root
    chown root:root "$chromeSandboxPath"
    # 设置权限为 4755
    chmod 4755 "$chromeSandboxPath"
    echo "chrome-sandbox 权限和所有者已设置。"
    else
    echo "警告:未找到 chrome-sandbox 文件:$chromeSandboxPath"
    fi

2.2 新建main.js,分平台编写代码

javascript
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
const { app, BrowserWindow, Menu } = require('electron')
const path = require('node:path')
app.commandLine.appendSwitch('ignore-certificate-errors') // 忽略证书错误

const createWindow = () => {
Menu.setApplicationMenu(null)
// 根据不同的操作系统选择不同的 preload 文件
let preloadPath = '';
switch (process.platform) {
case 'win32': // Windows
preloadPath = path.join(__dirname, 'platform/win32/win32Preload.js');
break;
case 'linux': // Linux
preloadPath = path.join(__dirname, 'platform/linux/linuxPreload.js');
break;
}
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: preloadPath, // 动态选择 preload 文件
contextIsolation: true, // 必须启用上下文隔离
nodeIntegration: false, // 禁用 Node.js 集成
}
})

// 加载 index.html
if (process.platform === 'win32') {
mainWindow.loadFile('./paltform/win32/win32.html')
// 打开开发工具
mainWindow.webContents.openDevTools()
} else if (process.platform === 'linux') {
mainWindow.loadFile('./paltform/linux/linux.html')
}
}
app.whenReady().then(() => {
createWindow()
// macOS
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
// win linux
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})


// 在当前文件中你可以引入所有的主进程代码 也可以拆分成几个文件,然后用 require 导入。
let platformCode
if (process.platform === 'win32') {
platformCode = require('./paltform/win32/win32Main.js')
} else if (process.platform === 'linux') {
platformCode = require('./paltform/linux/linuxMain.js')
}
platformCode()

目录结构

plaintext
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
project-name/

├── platform/
│   ├── linux/
│   │   └── linux.html
│   │   └── linuxMain.js
│   │   └── linuxPreload.js
│   │   └── linuxRenderer.js
│   ├── win32/
│   │   └── win32.html
│   │   └── win32Main.js
│   │   └── win32Preload.js
│   │   └── win32Renderer.js

...

3. 进程间通信

main为主进程代码,renderer为子进程(渲染进程代码),preload为进程通信控制代码

  • invoke/handle
    适用于渲染进程向主进程提交异步请求并期待返回的情况,例如接口请求,命令执行
  • send/on
    适用于单线发送消息的情况,类似udp