Electron 공식문서를 정리한 글입니다.
main 프로세스는 전체 운영체제 접근 권한을 가진 Node.js 환경이다. Electron 모듈 뿐만 아니라 Node.js 내장 모듈과 npm을 통한 설치된 패키지에도 접근할 수 있다. 반면, 보안상의 이유로 renderer 프로세스는 기본적으로 Node.js를 실행하지 않고 웹 페이지를 실행한다.Electron의 서로 다른 프로세스 유형을 연결하기 위해서, preload 스크립트를 사용해야 한다.
preload 스크립트는 HTML DOM 및 제한된 Node.js 및 Electron API에 접근할 수 있는 컨텍스트에서 실행된다.preload 스크립트는 renderer에서 웹 페이지가 로드되기 전에 주입되며, 크롬 확장 프로그램의 content 스크립트와 유사하다. 접근이 필요한 renderer에 기능을 추가하기 위해, contextBridge API를 통해 전역 객체를 정의할 수 있다.const { contextBridge } = require('electron')
contextBridge.exposeInMainWorld('versions', {
node: () => process.versions.node,
chrome: () => process.versions.chrome,
electron: () => process.versions.electron
// we can also expose variables, not just functions
})
const path = require('node:path')
const createWindow = () => {
const win = new BrowserWindow({
...
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
}
renderer 프로세스에서 versions 전역변수에 접근할 수 있다.
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()})`
info라는 id 속성을 가진 새 요소를 추가하고 renderer.js 스크립트를 첨부한 index.html
<!DOCTYPE html>
<html>
<head>
...
</head>
<body>
...
<p id="info"></p>
</body>
<script src="./renderer.js"></script>
</html>

main 프로세스와 renderer 프로세스는 구별된 책임을 가지고 있고 서로 교환할 수 없다. 이는 renderer 프로세스에서 직접적으로 Node.js API에 접근하거나, main 프로세스에서 HTML DOM에 직접적으로 접근하는 것이 불가능하다.ipcMain 및 ipcRenderer 모듈을 사용해 IPC(Inter-Process Communication)를 하면된다. 웹 페이지에서 main 프로세스로 메세지를 보내려면, ipcMain.handle로 main 프로세스 핸들러를 설정하고 preload 스크립트에서 이 핸들러를 트리거하는 ipcRenderer.invoke를 호출하는 함수를 노출하면 된다.const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('versions', {
...
ping: () => ipcRenderer.invoke('ping')
})
const { app, BrowserWindow, ipcMain } = require('electron')
const createWindow = () => {
...
}
app.whenReady().then(() => {
ipcMain.handle('ping', () => 'pong')
createWindow()
})
한 번 sender와 receiver를 설정하면, 아까 정의한 ‘ping’ 채널을 통해 renderer에서 main 프로세스로 메세지를 보낼 수 있다.
const func = async () => {
const response = await window.versions.ping()
console.log(response) // prints out 'pong'
}
func()