This is my notes while doing official electron tutorial.
Electron don't support ECMAscript import
s. Must use require
there is also option to debug using VScode. Might be useful later on.
goal :try previliged APIs on renderer, Electron's IPC
Electron's main process runs on node.js w/ full OS access, Electron modules, and npm packages. But renderer shouldn't for security reasons.
two new files, preload.js
, renderer.js
this will expose a versions
obj? or sth to electron rendere
// preload.js
const { contextBridge } = require("electron")
contextBridge.exposeInMainWorld('versions', {
node: () => process.versions.node,
chrome: () => process.versions.chrome,
electron: () => process.versions.electron,
})
and this renderer will modify some HTML elements, using the 'versions' object?'s getters
// 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()})`
notice the <p>
with id="info"
and added <script src='renderer.js>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'" />
<meta http-equiv="X-Content-Security-Policy" content="default-src 'self'; script-src 'self'" />
<title>Hello from Electron renderer!</title>
</head>
<body>
<h1>Hello from Electron renderer!</h1>
<p>👋</p>
<p id="info"></p>
</body>
<script src="./renderer.js"></script>
</html>
now for the IPC interprocess communication
electron's main and renderer process have its own responsibilities. so, main process can't access the HTML DOM, and rendere can't access nodejs APIs.
but electron has ipcMAin
, ipcRenderer
modules for the IPC. use this.
for security reasons, don't expose the whole ipcRenderer
module via preload script.
do it like this. wrap it in contextBridge
module.
// preload.js
contextBridge.exposeInMainWorld('versions', {
// ... skip
ping: () => ipcRenderer.invoke('ping'),
now write handler in main
// main.js
// setup handler before loading loadFile.
ipcMain.handle('ping', () => 'pong' )
win.loadFile('index.html')
then use it in renderer
// renderer.js
const func = async () => {
const response = await window.versions.ping()
console.log(response) // prints out 'pong'
}
func()
if pong
doesn't log, check developer tools of electron app, not terminal.
In macOS, you can go thru view
menu on top or option+cmd+I
if it logs undefined
, make sure arrow function returns sth
//ex
() => {'pong'} // wrong. executes code block on function call, but returns nothing
() => 'pong' // good. returns string
tutorial says some things, then says refer to its examples