跳至主要内容

[note] electron 筆記

概念

在 Electron 中分成 main process 和 renderer process:

  • renderer process 就像是作用在瀏覽器中的頁面一樣,它沒辦法直接取用到 Node.js 提供的 API
  • main process 的環境就如同在 Node.js,它也沒辦法直接取用 DOM API

另外有一個特別的橋樑,承作 preload,可以透過 webPreferences.preload 來設定,它能夠同時存取 Node.js API(main process)和 DOM(renderer process)。

共用資料

透過 contextBridge.exposeInMainWorld 可以暴露變數,讓變數在主程序(main process)和轉譯器程序(renderer process)間溝通:

建立要在主程序和 renderer 間可以互相溝通的變數:

// preload.js
const { contextBridge } = require('electron');

// 建立名稱 versions 的物件,這個物件可以在 renderer 被取用
contextBridge.exposeInMainWorld('versions', {
node: () => process.versions.node,
chrome: () => process.versions.chrome,
electron: () => process.versions.electron,
});

在 main process 註冊 preload:

// main.js
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
},
});

win.loadFile('index.html');
};

在 renderer 中取用變數:

// renderer.js
const information = document.getElementById('info');

information.innerText = `
This app is using Chrome (v${versions.chrome()}),
Node.js (v${versions.node()}),
and Electron (v${versions.electron()})
`;
<!-- index.html -->

<html>
<script src="./renderer.js"></script>
</html>

互相溝通

如果要讓 main process 以及 renderer process 間能夠溝通,就需要使用 Electron 提供的 ipcMainipcRenderer

暴露 invoke('ping') 的方法到 renderer:

// preload.js
const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('versions', {
// ...

// highligh-start
// 暴露 invoke('ping') 的方法到 renderer
ping: () => ipcRenderer.invoke('ping'),
});

main.js 處理收到事件時的動作(event handler):

// main.js
const { app, BrowserWindow, ipcMain } = require('electron');

const createWindow = () => {
const win = new BrowserWindow({
// ...
});

ipcMain.handle('ping', () => 'pong');

// ...
};

在 renderer process 則可以透過呼叫這個方法來與 main process 溝通:

// renderer.js
const func = async () => {
const response = await window.versions.ping();
console.log(response); // prints out 'pong'
};

func();

小技巧筆記

避免使用者縮放應用程式頁面

keywords: zoom
const { webFrame } = require('electron');

webFrame.setZoomFactor(1);
webFrame.setVisualZoomLevelLimits(1, 1);
webFrame.setLayoutZoomLevelLimits(0, 0);

Disable Zoom @ Electron Github Issues