[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 提供的 ipcMain
和 ipcRenderer
。
暴露 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