运行流程运行流程
运行的流程
主进程和渲染进程
关于主进程和渲染器进程
package.json
中定义的入口被称为主进程。 在主进程中实例化BrowserWindow
创建的Web
页面被称为渲染进程。 一个Electron
应用只有一个主进程,但是可以有多个渲染进程, 每个Electron
中的web
页面运行在它自己的渲染进程中。主进程使用
BrowserWindow
实例创建页面。 每个BrowserWindow
实例都在自己的 渲染进程里运行页面。 当一个BrowserWindow
实例被销毁后,相应的渲染进程也会被终止。
- 进程(了解):进程(
Process
)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。 - 线程(了解):在⼀一个程序里的一个执行路线就叫做线程(
thread
)。更准确的定义是: 线程是“一个进程内部的控制序列”。 - 线程和进程(了解):一个程序至少有一个进程,一个进程至少有一个线程。
主进程和渲染进程案例
const { app, BrowserWindow } = require("electron");
const path = require("path");
const createWindow = () => {
const mainWindow = new BrowserWindow({ width: 600, height: 400 });
mainWindow.loadFile(path.join(__dirname, "index.html"));
const secondWindow=new BrowserWindow({
width: 300,
height: 200,
parent: mainWindow,
});
secondWindow.loadFile(path.join(__dirname, "second.html"));
}
// 监听应用的启动事件
app.on("ready", createWindow)
// 监听窗口关闭的事件,关闭的时候退出应用
macOs 需要排除 app.on('window-all-closed', () => {
if (process.platform !== 'darwin') { app.quit(); }
});
// Macos 中点击 dock 中的应用图标的时候重新创建窗口
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
主进程 和 渲染进程中使用 Nodejs 以及 Nodejs 第三方模块
- 主进程中无需任何配置就可以使用
nodejs
模块。
BrowserWindow
中通过preload
加载的js
文件可以直接使用nodejs
模块。- 如果不使用
preload
加载的js
,Electron5.x
之后没法在渲染进程中直接使用nodejs
, 如果我们想在渲染进程中使用nodejs
的话需要进行如下配置。
mainWindow=new BrowserWindow({
width:800,
height:600,
webPreferences: {
nodeIntegration: true,
contextIsolation:false
}
});
BrowserWindow 中通过 preload 加载的 js 文件可以直接使用 nodejs 模块
- 在页面运行其他脚本之前预先加载指定的脚本 无论页面是否集成
Node
, 此脚本都可以访 问所有Node API
脚本路径为文件的绝对路径。
const createWindow = () => {
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences:{
preload:path.join(__dirname, "renderer/preload.js")
}
});
mainWindow.loadFile(path.join(__dirname, "index.html"));
}
renderer/preload.js 渲染进程代码
const fs =require("fs");
fs.readFile("package.json", (err, data) => {
if (err) {
console.log(err)。
return;
}
console.log(data.toString());
})
渲染进程中直接使用 Nodejs 模块
如果不使用
preload
加载的js
,Electron5.x
之后没法在渲染进程中直接使用nodejs
, 如果我们想在渲染进程中使用nodejs
的话需要进行如下配置。
mainWindow=new BrowserWindow({
width:800,
height:600,
webPreferences: {
nodeIntegration: true,
contextIsolation:false
}
});
主进程
const { app, BrowserWindow } = require("electron");
const path = require("path");
const createWindow = () => {
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences:{ // preload:path.join(__dirname, "renderer/preload.js"),
nodeIntegration:true,
contextIsolation:false
}
});
mainWindow.loadFile(path.join(__dirname, "index.html")); //打开 DevTools
mainWindow.webContents.openDevTools();
}
渲染进程
const fs =require("fs");
fs.readFile("package.json",(err ,data) => {
if (err) {
console.log(err);
return;
}
console.log(data.toString());
})
渲染进程和主进程中使用 Nodejs 第三方模块
- 安装模块
- 引入模块
- 参考第三方文档使用
开启调试模式
开启调试模式
mainWindow.webContents.openDevTools();
完整代码
const { app, BrowserWindow } = require("electron");
const path = require("path");
const createWindow = () => {
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences:{
nodeIntegration: true,
contextIsolation: false
}
});
mainWindow.loadFile(path.join(__dirname, "index.html")); //打开 DevTools
mainWindow.webContents.openDevTools();
}
渲染进程中使用 nodejs 模块的案例
- 创建预加载脚本,并在其中使用
contextBridge
暴露fs
功能。
preload.js
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electronAPI', {
readFile: (filePath) => ipcRenderer.invoke('read-file', filePath)
});
- 在主进程中创建
BrowserWindow
时指定预加载脚本。
main.js
const win = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true // 推荐开启上下文隔离
}
});
- 在主进程中处理
IPC
事件。
main.js
ipcMain.handle('read-file', async (event, path) => {
const fs = require('fs');
const data = fs.readFileSync(path, 'utf8');
return data;
});
- 在渲染进程中通过暴露的
API
调用功能。
window.electronAPI.readFile('文件路径').then((data) => {
console.log(data);
});
IPC事件
IPC事件
(Inter-Process Communication events)指的是在不同进程之间进行通信的事件。 在许多应用程序中,特别是在使用Electron
这样的框架开发桌面应用时,IPC
事件是一个关键概念。
在 Electron 中的 IPC
在
Electron
框架中,IPC
事件被广泛用于在主进程(Main Process)
和渲染进程(Renderer Process)
之间进行通信。主进程:运行包管理和窗口控制的
Node.js
进程。渲染进程:类似于
Web
浏览器中的标签页,它是一个展示用户界面的Web
页面。
由于安全原因,这两种类型的进程在 Electron
中是隔离的,因此需要一种机制来进行通信。这就是 IPC
事件的作用。
IPC事件的工作原理
- 发送方:一个进程(发送方)通过发送
IPC
事件来请求信息或触发在另一个进程(接收方)中的操作。 - 接收方:接收方监听这些事件,并在事件发生时作出响应。
- 数据交换:
IPC
事件可以携带数据,使进程间的通信更加灵活。
Electron中的IPC模块
Electron
提供了两个模块来支持 IPC
:
ipcMain
:在主进程中使用,用于监听来自渲染进程的消息。
ipcRenderer
:在渲染进程中使用,用于发送消息到主进程和从主进程接收消息。
示例
假设你在渲染进程中有一个按钮,点击后需要在主进程中执行某个操作:
const { ipcRenderer } = require('electron');
// 发送一个IPC事件到主进程
ipcRenderer.send('perform-action', { /* 数据 */ });
在主进程(ipcMain)
const { ipcMain } = require('electron');
// 监听来自渲染进程的IPC事件
ipcMain.on('perform-action', (event, args) => {
// 执行操作...
});
IPC事件是在不同进程间进行通信的重要机制,特别是在Electron这种多进程架构的应用中。它允许数据和消息在应用的不同部分之间安全地传递。