Hands on Electron 🔗
Arch 🔗
Main(Node) + Renderer(Chrome)
-
main.js
: the entry point of electron -
index.html
: the main page of app, it will be loaded into renderer process -
renderer.js
: This file is loaded via the tag in the index.html file and will be executed in the renderer process for that window. No Node.js APIs are available in this process becausenodeIntegration
is turned off andcontextIsolation
is turned on. Use the contextBridge API inpreload.js
to expose Node.js functionality from the main process. -
preload.js
: it’s a script loaded beforeindex.html
by renderer process, like Chrome extension content script.
preload.js is default sandboxed
Process Communication 🔗
preload.js
==>renderer.js
use contextBridge API to define global vars
const { contextBridge } = require('electron')
contextBridge.exposeInMainWorld('versions', {
node: () => process.versions.node,
chrome: () => process.versions.chrome,
electron: () => process.versions.electron,
// 能暴露的不仅仅是函数,我们还可以暴露变量
})
- IPC
communicate between main process and renderer process, use IPC module(ipcMain
+ ipcRenderer
)
renderer.js
==>main.js
first, expose invoke
call to renderer.js in preload.js:
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('versions', {
node: () => process.versions.node,
chrome: () => process.versions.chrome,
electron: () => process.versions.electron,
ping: () => ipcRenderer.invoke('ping'),
// 能暴露的不仅仅是函数,我们还可以暴露变量
})
second, register event handler in main.js
:
const { app, BrowserWindow, ipcMain } = require('electron')
const path = require('path')
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
},
})
ipcMain.handle('ping', () => 'pong')
win.loadFile('index.html')
}
app.whenReady().then(createWindow)
finally, use invoke
call in your renderer.js:
const func = async () => {
const response = await window.versions.ping()
console.log(response) // 打印 'pong'
}
func()