ModĂšle de processus
Electron hérite son architecture multi-processus de Chromium, ce qui rend le framework trÚs similaire dans son architecture à un navigateur web moderne. This guide will expand on the concepts applied in the Tutorial.
Et pourquoi pas un seul processus ?â
Les navigateurs Web sont des applications incroyablement compliquĂ©es. Outre leur fonction principale d 'affichage de contenu Web, ils ont de nombreuses fonctionnalitĂ©s secondaires, telles que la gestion de plusieurs fenĂȘtres (ou onglets) et le chargement dâextensions tierces.
Dans les premiers temps, les navigateurs utilisaient généralement un seul processus pour toutes ces fonctionnalités . Bien que ce modÚle signifiait moins d'usage de ressource pour chaque onglet ouvert, cela signifiait également que lorsqu'un site Web se plantait cela affectait l'ensemble du navigateur.
Le modĂšle multi-processusâ
Pour résoudre ce problÚme, l'équipe de Chrome a décidé que chaque onglet serait rendu dans son propre processus , limitant ainsi les dommages qu'un code bogué ou malveillant d'une page web pourrait causer à l'application dans son ensemble. Un seul processus de navigateur contrÎle ensuite ces processus ainsi que que le cycle de vie de l'application dans son ensemble. Le diagramme ci-dessous issu de la Bd Chrome illustre ce modÚle :
Les applications Electron sont structurĂ©es de maniĂšre trĂšs similaire. En tant que dĂ©veloppeur dâapplications, vous contrĂŽlez deux types de processus : principal et de rendu. Ceux-ci sont analogues aux propres processus de navigateur et de rendu de Chrome dĂ©crits ci-dessus.
Le processus principalâ
Chaque application Electron ne possÚde qu'un seul processus principal, celui-ci sert de point d'entrée à l'application. Le processus principal s'exécute dans un environnement Node.js, ce qui signifie qu'il a la capacité d'ajouter des modules à l'aide de require
et d'utiliser toutes les API Node.js.
Gestion des fenĂȘtresâ
The main process' primary purpose is to create and manage application windows with the BrowserWindow
module.
Chaque instance de la classe BrowserWindow
crĂ©e une fenĂȘtre dâapplication qui charge une page Web dans un processus de rendu distinct. You can interact with this web content from the main process using the window's webContents
object.
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ width: 800, height: 1500 })
win.loadURL('https://github.com')
const contents = win.webContents
console.log(contents)
[!NOTE] A renderer process is also created for web embeds such as the
BrowserView
module. Et dans de tels cas lâobjetwebContents
est également accessible.
Ătant donnĂ© que le module BrowserWindow
est du type EventEmitter
, vous pouvez tout Ă fait ajouter des gestionnaires pour divers Ă©vĂ©nements utilisateur (par exemple, lors de la rĂ©duction ou de l'agrandissement une fenĂȘtre).
Lors de la destruction dâune instance de BrowserWindow
, le processus de rendu correspondant est arrĂȘtĂ©.
Cycle de vie de lâapplicationâ
The main process also controls your application's lifecycle through Electron's app
module. This module provides a large set of events and methods that you can use to add custom application behavior (for instance, programmatically quitting your application, modifying the application dock, or showing an About panel).
As a practical example, the app shown in the tutorial starter code uses app
APIs to create a more native application window experience.
//quitter lâapplication lorsquâaucune fenĂȘtre nâest ouverte sur les plates-formes non macOS
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})
API nativesâ
Pour Ă©tendre les fonctionnalitĂ©s dâElectron au-delĂ de celles d'un simple wrapper de Chromium pour du contenu Web, le processus principal ajoute Ă©galement des API personnalisĂ©es pour interagir avec le systĂšme dâexploitation de lâutilisateur. Electron expose diffĂ©rents modules qui contrĂŽlent les fonctionnalitĂ©s de bureau natives, telles que les menus, les boĂźtes de dialogue et les icĂŽnes de la barre de tĂąches.
Pour une liste complĂšte des modules du processus principal dâElectron, consultez notre documentation de l'API.
Le processus de renduâ
Chaque application Electron génÚre un processus de rendu distinct pour toute BrowserWindow
ouverte (ainsi que pour chaque contenu web intĂ©grĂ©). Comme son nom l'indique, un moteur de rendu (renderer) est responsable du rendu de contenu web. A toutes fins utiles, le code exĂ©cutĂ© dans les processus de rendu devrait se comporter selon les standards web (au moins de la mĂȘme façon que Chromium).
Par consĂ©quent, toutes les interfaces utilisateur et fonctionnalitĂ©s de l'application au sein d'une fenĂȘtre seront Ă©crites avec les mĂȘmes outils et paradigmes que vous utilisez pour le Web .
Bien que l'explication de chaque spécification web soit hors de la portée de ce guide, les points suivants représentent le minimum vital pour comprendre:
- Votre point d'entrée pour le processus de rendu est un fichier HTML.
- Le style de l'interface utilisateur est ajouté via des feuilles de style (CSS).
- Le code JavaScript exĂ©cutable peut ĂȘtre ajoutĂ© via des Ă©lĂ©ments
<script>
.
De plus, cela signifie Ă©galement que le moteur de rendu nâa pas dâaccĂšs direct Ă require
ou Ă dâautres API Node.js. Pour inclure directement des modules NPM dans le moteur de rendu, vous devez utiliser les mĂȘmes chaĂźnes dâoutils de groupage (par exemple, webpack
ou parcel
) que ceux utilisés pour le Web.
Les processus de rendu peuvent ĂȘtre gĂ©nĂ©rĂ©s avec un environnement Node.js complet pour faciliter le dĂ©veloppement . Historiquement, c'Ă©tait d'ailleurs la valeur par dĂ©faut, mais cette fonctionnalitĂ© a Ă©tĂ© dĂ©sactivĂ©e pour des raisons de sĂ©curitĂ©.
à ce stade, vous pouvez vous demander comment vos interfaces utilisateur de processus de rendu peuvent interagir avec Node.js et les fonctionnalités natives d'Electron si ces fonctionnalités ne sont accessibles que depuis le processus principal. En fait, il n'y a pas de moyen direct d'importer des scripts de contenu d'Electron.
Scripts de prĂ©chargementâ
Les scripts de prĂ©chargement (preload) contiennent du code qui s'exĂ©cute dans un processus de rendu (renderer process) avant que son contenu web ne se charge. Ces scripts sâexĂ©cutent dans le contexte du moteur de rendu, mais ont des privilĂšges supplĂ©mentaires qui leur donnent accĂšs aux API Node.js.
Un script de prĂ©chargement peut ĂȘtre attachĂ© au processus principal Ă l'aide de lâoption webPreferences
du constructeur de BrowserWindow
.
const { BrowserWindow } = require('electron')
// ...
const win = new BrowserWindow({
webPreferences: {
preload: 'path/to/preload.js'
}
})
// ...
Comme le script de préchargement partage une interface Window
globale avec les moteurs de rendu et peut accĂ©der aux API Node.js, il va ĂȘtre utilisĂ© pour enrichir votre moteur de rendu en exposant des API diverses dans le window
global qui seront utilsables ensuite par votre contenu Web.
Although preload scripts share a window
global with the renderer they're attached to, you cannot directly attach any variables from the preload script to window
because of the contextIsolation
default.
window.myAPI = {
desktop: true
}
console.log(window.myAPI)
// => undefined
L'isolement du contexte (contextIsolation) implique que les scripts de prĂ©chargement sont isolĂ©s du monde principal(mainworld) du moteur de rendu pour Ă©viter toute brĂȘche donnant accĂšs Ă des API privilĂ©giĂ©es dans le code de votre contenu web.
Instead, use the contextBridge
module to accomplish this securely:
const { contextBridge } = require('electron')
contextBridge.exposeInMainWorld('myAPI', {
desktop: true
})
console.log(window.myAPI)
// => { desktop: true }
Cette fonctionnalité est incroyablement utile pour deux raisons principales:
- By exposing
ipcRenderer
helpers to the renderer, you can use inter-process communication (IPC) to trigger main process tasks from the renderer (and vice-versa). - Si vous développez un wrapper Electron pour une application web existante hébergée sur une URL distante, vous pouvez ajouter des propriétés personnalisées au
window
global du moteur de rendu pouvant ĂȘtre utilisĂ©es uniquement du cĂŽtĂ© du client Web de l'appli de bureau.
Utility-processâ
Each Electron app can spawn multiple child processes from the main process using the UtilityProcess API. Un processus utilitaire s'exécute dans un environnement Node.js, ce qui signifie qu'il a la capacité d'inclure des modules par require
et d'utiliser toutes les API Node.js. Un tel processus peut ĂȘtre utilisĂ© pour hĂ©berger par exemple : des services non approuvĂ©s, des tĂąches intensives en CPU ou des composants susceptibles de planter qui auraient Ă©tĂ© prĂ©cĂ©demment hĂ©bergĂ©s dans le processus principal ou un processus créé avec l'API de Node.js child_process.fork
. La différence principale entre un processus utilitaire et un processus créé par le module child_process de Node.js, est que l'utilitaire peut établir un canal de communication avec un processus de rendu en utilisant MessagePort
. An Electron app can always prefer the UtilityProcess API over Node.js child_process.fork
API when there is need to fork a child process from the main process.
Alias du module spĂ©cifiques au processus (TypeScript)â
Le package npm d'Electron exporte également des sous-chemins qui contiennent un sous-ensemble de définitions de type TypeScript d'Electron.
electron/main
inclut les types pour tous les modules du processus principal.electron/renderer
inclut les types pour tous les modules de processus de rendu.electron/common
inclut les types de modules pouvant ĂȘtre exĂ©cutĂ©s dans les processus principaux et de rendu.
Ces alias n'ont aucun impact sur l'exĂ©cution, mais peuvent ĂȘtre utilisĂ©s pour le controle des types ainsi que l'auto-complĂ©tion.
const { shell } = require('electron/common')
const { app } = require('electron/main')