前一篇文章已经介绍了如何创建一个electron项目,没有看过的小伙伴可以去实操一下。
接下来给大家介绍一下electron项目的架构是什么样的。
electron之快速上手
electron项目一般有两个进程:主进程和渲染进程。
- 主进程:整个项目的唯一入口,可以在这个进程中调用require和所有nodejs的api;
- 渲染进程:electron项目中每个BrowserWindow都会拥有一个对立的渲染器进程来渲染网页;
主进程
在创建项目的时候会创建一个项目入口js文件,一般命名为main.js,在这个进程中开业调用所有nodejs的api以及electron提供的原生桌面的功能模块。
main.js
const { app, BrowserWindow } = require('electron')
const {join} = require("path");// 应用创建窗口
const createWindow = () => {const win = new BrowserWindow({width: 800,height: 600})win.loadFile('index.html')
}app.whenReady().then(() => {createWindow()
})
渲染进程
渲染进程由主进程创建,也被称为浏览器进程,它主要负责显示网页内容。
每个网页窗口都在自己的渲染进程中运行,这样可以防止一个网页崩溃影响到其他的网页。
在运行主进程的时候可以通过创建一个BrowserWindow对象来创建网页窗口。
在主进程中执行下面代码可以创建一个指定宽高的窗口,然后通过win的loadFile方法加载窗口的入口html文件,在html中可以添加css样式文
const win = new BrowserWindow({width: 800,height: 600,
})
win.loadFile('index.html')
index.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><label>用户名:<input type="text"></label>
</body>
</html>
渲染结果
上面的窗口以及完美的呈现出来了,如果想把输入的用户名保存到磁盘中要怎么操作呢?这就需要到下面的进程间通信了。
进程间通信
主进程可以调用nodejs的api以及原生桌面的功能模块,渲染进程可以根据实际业务页面窗口展示的内容。
渲染进程不能直接调用nodejs的api,主线程也不能直接修改页面窗口的内容。
这个时候就需要用到进程间通信。
预加载脚本preload
先说一下preload脚本文件。
preload脚本运行于渲染进程中,会在网页加载之前先执行preload.js,
并且可以访问nodejs的api以及其他主进程可以使用的功能模块。
ipcMain和ipcRenderer
进程间通信的核心是ipcMain和ipcRenderer两个模块,它们继承了nodejs的事件模块,通信的本质就是事件的处理。
由于篇幅原因,这里只简单介绍一下渲染进程到主进程的通信,后面会把进程间通信再详细介绍。
创建一个preload.js文件
通过下面代码会暴露一个api到window中,
当网页调用window.myAPI.saveName
方法的时候会通过ipcRenderer.send触发save-name
事件
const { contextBridge, ipcRenderer } = require('electron')contextBridge.exposeInMainWorld('myAPI', {saveName: (title) => ipcRenderer.send('save-name', title)
})
在创建BrowserWindow对象的时候配置preload.js文件
const win = new BrowserWindow({width: 800,height: 600,webPreferences: {preload: join(__dirname, 'preload.js')}
})
在主进程中监听save-name
事件,当ipcRenderer.send('save-name', title)
执行的时候就会触发这里的业务逻辑
ipcMain.on('saveName', (e, userName) => {console.log(userName);//此处省略保存的代码逻辑
})
main.js的完整代码
const { app, BrowserWindow, ipcMain } = require('electron')
const {join} = require("path");// 应用创建窗口
const createWindow = () => {const win = new BrowserWindow({width: 800,height: 600,webPreferences: {preload: join(__dirname, 'preload.js')}})ipcMain.on('saveName', (e, userName) => {console.log(userName);//此处省略保存的代码逻辑})win.loadFile('index.html')
}app.whenReady().then(() => {createWindow()
})
运行项目
当点击保存按钮时,就会在主进程控制台打印输入框的内容