Unlike NW.js that shares the context of the browser and Node in the same process which allows running packages npm and access the browser’s API in the same file .js
, Electron does differently, in Electron each context is executed in an isolated process, the way Node and the code "front-end" communicate is through messages.
Messages:
Both the code in the main process and the rendering process use an instance of Eventemitter to exchange messages ... in the main process the module is used ipcMan or the property "webContents" of "Browserwindow":
// use ipcMain no processo principal (sync/async) ----------------
const {ipcMain} = require('electron')
// ouvinte, resposta assíncrona
ipcMain.on('iniciar-player', (event, arg) => {
// sua lógica aqui ...
event.sender.send('player-reply', 'started-async')
})
// ouvinte, resposta síncrona
ipcMain.on('iniciar-player', (event, arg) => {
// sua lógica aqui ...
event.returnValue = 'started-sync'
})
// no processo de renderização (página web) ----------------------
const {ipcRenderer} = require('electron')
// ouvinte assíncrono (ouvinte antes do envio)
ipcRenderer.on('player-reply', (event, arg) => {
console.log(arg) // "started-async"
})
// enviar
ipcRenderer.send('iniciar-player', 'argumento-ou-configuração')
// ouvinte síncrono
let response = ipcRenderer.sendSync('iniciar-player', 'argumento-ou-configuração')
console.log(response) // "started-sync"
In the main process run the logic of your module. The next example uses "webContents" in the main proceedings (asynchronously):
// no processo principal (async) ---------------------------------
const {app, BrowserWindow} = require('electron')
let win = null
app.on('ready', () => {
win = new BrowserWindow({width: 800, height: 600})
win.loadURL(`file://${__dirname}/app/public/index.html`)
// ouvinte
win.webContents.on('iniciar-player', (/*parametros serializados em JSON por padrão*/) => {
// sua lógica ...
win.webContents.send('player-reply', 'started-async') // responda
})
})
// no processo de renderização (página web) ----------------------
const {ipcRenderer} = require('electron')
// ouvinte assíncrono (ouvinte antes do envio)
ipcRenderer.on('player-reply', (event, arg) => {
console.log(arg) // "started-async"
})
// enviar
ipcRenderer.send('iniciar-player', 'argumento-ou-configuração')
This is the basics of exchanging messages between the code executed on the page (render) and the main process (main).
Note: you can still get rid of these messages using the module remote if you only want to access the module without going through the main process
Remote:
You can access a module or file in the rendering process (.js
) in particular through the module remote:
// no processo de renderização (página web)
const player = require('electron').remote.require('play-sound')
// abrir player
const audio = player.play('nomedoarquivo.mp3', {/*efeitos*/}, (err) => {
if (err) throw err
});
// simulando a iteração do usuário para encerrar o player
document.getElementById('btn-fechar-player').addEventListener('click', () => {
audio.kill()
}, false)
Use remote looks much simpler, but read the documentation ... "some things" are not recommended to do when using remote.
Sources:
Not wanting to look "pedantic", even if the issue has already been resolved I recommend reformulating its title because: an Electron app cannot be defined as a website. This helps the community.
– Lauro Moraes