Aller au contenu principal

Démarrage Rapide

Ce tutoriel vous guidera dans le processus de création d'une application Hello World avec Electron, similaire à electron/electron-quick-start.

À la fin de ce tutoriel, votre application ouvrira une fenêtre de navigateur qui affichera une page web avec des informations sur les versions de Chromium, de Node.js et d'Electron en cours d'exécution.

Prérequis

Pour utiliser Electron, vous devez installer Node.js. Nous vous recommandons d'utiliser la dernière version LTS disponible.

Veuillez installer Node.js en utilisant des installateurs pré-compilés pour votre plate-forme. Sinon, vous risquez de rencontrer des problèmes d'incompatibilité avec différents outils de développement.

Vous pouvez vérifier que Node.js a été installé correctement en saisissant les commandes suivantes dans votre terminal :

node -v
npm -v

Les commandes devraient afficher respectivement les versions de Node.js et de npm.

Remarque : Puisque Electron embarque Node.js dans son binaire, la version de Node.js exécutant votre code n'est pas liée à la version en cours d'exécution sur votre système.

Créer votre application

Initialisation du projet

Les applications Electron suivent la même structure générale que les autres projets Node.js. Vous allez donc commencer par créer un dossier et initialiser un package npm.

mkdir my-electron-app && cd my-electron-app
npm init

La commande interactive init vous demandera de définir quelques champs dans votre configuration. Quelques règles devront être suivies pour les besoins de ce tutoriel:

  • entry point doit être main.js.
  • author et description peuvent prendre n’importe quelle valeur, mais sont nécessaires pour le packaging de l'application.

Votre fichier package.json devrait ressembler à ceci :

{
"name": "my-electron-app",
"version": "1.0.0",
"description": "Hello World!",
"main": "main.js",
"author": "Jane Doe",
"license": "MIT"
}

Ensuite, installez le package electron dans les devDependencies de votre application.

npm install --save-dev electron

Remarque : Si vous rencontrez des problèmes avec l'installation d'Electron, veuillez consulter le guide Instructions d’installation avancée.

Enfin, comme vous devez pouvoir exécuter Electron. ajoutez une commande start dans le champ scripts de votre fichier de configuration package.json , comme suit :

{
"scripts": {
"start": "electron ."
}
}

Cette commande start vous permettra d'ouvrir votre application en mode développement.

npm start

Remarque : Ce script indique à Electron de s’exécuter à la racine du dossier de votre projet( le point suivant la commande electron). À ce stade, votre application va immédiatement lancer une erreur vous disant qu'elle ne trouve pas d'application à exécuter.

Exécuter le processus principal

Le point d’entrée de toute application Electron est son script main. Ce script contrôle le processus principal, celui-ci s'exécute dans un environnement Node.js et gèrer le cycle de vie de votre application, en plus, il affiche les interfaces natives, effectue des opérations privilégiées et gére les processus de rendu (plus d'information à ce sujet viendra par la suite).

Pendant l’exécution, Electron va rechercher le nom de ce script dans le champ main du fichier de configuration package.json que vous avez dû configurer lors de l’étape Initialisation du projet.

Pour initialiser le script main, créez un fichier vide nommé main.js dans le dossier racine de votre projet.

Remarque : Si vous exécutez à nouveau le script start à ce stade, votre application ne lancera plus d'erreur ! Cependant, elle ne fera rien pour le moment parce que nous n'avons pas ajouté de code dans main.js.

Créer une page Web

Avant de pouvoir créer une fenêtre pour notre application, nous devons créer le contenu qui y sera chargé. Dans Electron, chaque fenêtre affiche du contenu Web pouvant être chargé à partir d'un fichier HTML local ou d'une URL distante.

Pour ce tutoriel, vous allez utiliser la première possibilité. Vous allez donc créer un fichier index.html à la racine de votre projet :

<!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'">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
Nous utilisons Node.js <span id="node-version"></span>,
Chromium <span id="chrome-version"></span>,
et Electron <span id="electron-version"></span>.
</body>
</html>

Remarque : en regardant ce document HTML, vous pouvez observer que les numéros de version sont absents du texte du body. Nous les insérerons manuellement plus tard à l’aide de JavaScript.

Ouverture de votre page web dans une fenêtre de navigateur

Maintenant que vous avez une page web, chargez-la dans une fenêtre d'application. Pour ce faire, vous aurez besoin de deux modules Electron :

  • Le module app, qui contrôle le cycle de vie des événements de votre application.
  • Le module BrowserWindow, qui crée et gère les fenêtres d’application.

Because the main process runs Node.js, you can import these as CommonJS modules at the top of your main.js file:

const { app, BrowserWindow } = require('electron')

Ensuite, ajoutez une fonction createWindow() qui charge index.html dans une nouvelle instance BrowserWindow.

const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600
})

win.loadFile('index.html')
}

Puis, appelez cette fonction createWindow() pour ouvrir votre fenêtre.

Dans Electron, les BrowserWindows ne peuvent être créées qu'après le déclenchement de l’événement ready du module app. Vous pouvez attendre cet événement en utilisant l'API app.whenReady(). Appelez createWindow() une fois que whenReady() a résolu sa Promise.

app.whenReady().then(() => {
createWindow()
})

Remarque : À ce stade, votre application Electron devrait ouvrir avec succès une fenêtre qui affiche votre page web !

Gérer le cycle de vie de votre fenêtre

Bien que vous puissiez maintenant ouvrir une BrowserWindow, vous aurez besoin de code standard supplémentaire pour qu'elle semble plus native pour chaque plate-forme. En effet, les fenêtres d’application se comportent différemment sur chaque système d’exploitation et avec Electron il est de votre responsabilité en tant que développeur d’implémenter leurs conventions dans vos applications.

En général, vous pourrez utiliser l'attribut platform de la variable globale process pour exécuter du code spécifique aux différent systèmes d’exploitation.

Quitter l'application lorsque toutes les fenêtres sont fermées (Windows & Linux)

Sur Windows et Linux, le fait de fermer toutes les fenêtres ferme généralement entièrement l'application.

Pour implémenter cette sortie de l'application vous devez écouter l’événement 'window-all-closed' du module app et appeler app.quit() si l’utilisateur n’est pas sous macOS (darwin).

app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})

Ouvrir une fenêtre si aucune n'est ouverte (macOS)

Alors que les applications Linux et Windows se ferment lorsqu'elles n'ont pas de fenêtres ouvertes, les applications macOS continuent généralement de s'exécuter même sans aucune fenêtre ouverte et activer une application lorsque aucune fenêtre n'est disponible en ouvre une nouvelle.

Pour implémenter cette fonctionnalité, écoutez l'événement activate du module app et appelez votre méthode existante createWindow() si aucune fenêtre de navigateur n'est ouverte.

Étant donné que les fenêtres ne peuvent pas être créées avant l'événement ready , vous ne devez écouter l'événement activate qu'après l'initialisation de votre application. Pour ce faire, attachez votre event listener à l'intérieur de votre callback whenReady() existante.

app.whenReady().then(() => {
createWindow()

app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})

Remarque: À ce stade, vos contrôles de fenêtre doivent être entièrement fonctionnels!

Accéder à Node.js depuis le moteur de rendu avec un script de préchargement

Maintenant, la dernière chose à faire est d'afficher sur votre page web les numéros de version d'Electron et de ses dépendances .

L’accès à ces informations est trivial à obtenir dans le processus principal via l’objet global process de Node. Cependant, vous ne pouvez pas aussi simplement modifier le DOM à partir du processus principal car il n'a pas accès au contexte du document du moteur de rendu. Il s'agit en effet de processus entièrement différents!

Note: Si vous avez besoin d'informations approfondies à propos des Processus, veillez consulter la documentation Modèle de processus .

C'est là que le rattachement d'un script de preload à votre moteur de rendu est pratique. Un tel script de préchargement s'exécute avant que le processus de rendu ne soit chargé et a accès à la fois aux globales de rendu (c.a.d. window et document) et à l'environnement Node.js.

Création d'un nouveau script nommé preload.js :

window.addEventListener('DOMContentLoaded', () => {
const replaceText = (selector, text) => {
const element = document.getElementById(selector)
if (element) element.innerText = text
}

for (const dependency of ['chrome', 'node', 'electron']) {
replaceText(`${dependency}-version`, process.versions[dependency])
}
})

Le code ci-dessus accède à l'objet process.versions de Node.js et exécute une simple fonction helper: replaceText pour insérer les numéros de version dans le document HTML.

Pour attacher ce script à votre processus de rendu, vous devez passer le chemin d’accès à votre script de préchargement via l’option webPreferences.preload dans votre constructeur de BrowserWindow existant.

const { app, BrowserWindow } = require('electron')
// inclusion du chemin du module Node.js au tout début de votre fichier
const path = require('node:path')

// modification de votre fonction existante createWindow()
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})

win.loadFile('index.html')
}
// ...

Deux concepts de Node.js sont utilisés ici :

  • La chaîne de caractères __dirname pointe vers le chemin du script en cours d'exécution (dans notre cas, le dossier racine de votre projet).
  • L'API path.join assemble plusieurs parties de path, créant un chemin sous forme d'une chaîne de caractères fonctionnant sur toutes les plateformes.

Nous utilisons un chemin relatif au fichier JavaScript en cours d'exécution afin que votre chemin relatif fonctionne en mode développement et en mode packaged.

Bonus : Ajoutez des fonctionnalités à vos contenus web

À ce stade, vous vous demandez peut êtrer comment ajouter plus de fonctionnalités à votre application.

Pour toute interaction avec votre contenu web, vous pourrez ajouter des scripts à votre processus de rendu. Puisque que le moteur de rendu fonctionne dans un environnement web normal, vous pouvez ajouter une balise <script> juste avant la balise de fermeture </body> du fichier index.html pour y inclure n'importe quel script de votre choix :

<script src="./renderer.js"></script>

Le code contenu dans renderer.js peut alors utiliser les mêmes APIs JavaScript et outils que vous utilisez pour votre développement front-end usuel, comme webpack pour regrouper et minifier votre code ou React pour gérer vos interfaces utilisateur.

Récapitulatif

Après avoir suivi les étapes ci-dessus, vous devriez avoir une application Electron entièrement fonctionnelle ressemblant à ceci :

Application Electron la plus simple

Le code complet est disponible ci-dessous :

// main.js

// Modules pour la gestion de l'appli et la création de la BrowserWindow native browser window
const { app, BrowserWindow } = require('electron')
const path = require('node:path')

const createWindow = () => {
// Création de la browser window.
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})

// et chargement de l'index.html de l'application.
mainWindow.loadFile('index.html')

// Ouvrir les outils de développement.
// mainWindow.webContents.openDevTools()
}

// Cette méthode sera appelée quand Electron aura fini
// de s'initialiser et sera prêt à créer des fenêtres de navigation.
// Certaines APIs peuvent être utilisées uniquement quant cet événement est émit.
app.whenReady().then(() => {
createWindow()

app.on('activate', () => {
// Sur macOS il est commun de re-créer une fenêtre lors
// du click sur l'icone du dock et qu'il n'y a pas d'autre fenêtre ouverte.
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})

// Quitter quand toutes les fenêtres sont fermées, sauf sur macOS. Dans ce cas il est courant
// que les applications et barre de menu restents actives jusqu'à ce que l'utilisateur quitte
// de manière explicite par Cmd + Q.
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})

// Dans ce fichier vous pouvez inclure le reste du code spécifique au processus principal. Vous pouvez également le mettre dans des fichiers séparés et les inclure ici.
// preload.js

// Toutes les API Node.js sont disponibles dans le processus de préchargement.
// Il a la même sandbox qu'une extension Chrome.
window.addEventListener('DOMContentLoaded', () => {
const replaceText = (selector, text) => {
const element = document.getElementById(selector)
if (element) element.innerText = text
}

for (const dependency of ['chrome', 'node', 'electron']) {
replaceText(`${dependency}-version`, process.versions[dependency])
}
})
<!--index.html-->

<!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'">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
Nous utilisons Node.js <span id="node-version"></span>,
Chromium <span id="chrome-version"></span>,
et Electron <span id="electron-version"></span>.

<!-- Vous pouvez également demander que d’autres fichiers s’exécutent dans ce processus -->
<script src="./renderer.js"></script>
</body>
</html>
const { app, BrowserWindow } = require('electron/main')
const path = require('node:path')

function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})

win.loadFile('index.html')
}

app.whenReady().then(() => {
createWindow()

app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
})

app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})

Pour résumer voici les étapes que nous avons franchies:

  • Nous avons amorcé une application Node.js et ajouté Electron en tant que dépendance.

  • Nous avons créé un script main.js qui exécute notre processus principal, qui va contrôler notre application et s'exécute dans un environnement Node.js. Dans ce script, nous avons utilisé les modules d'Electron app et BrowserWindow pour créer une fenêtre BrowserWindow qui affiche le contenu web dans un processus séparé (le moteur de rendu).

  • Afin d'accéder à certaines fonctionnalités de Node.js dans le moteur de rendu, nous avons attaché un script de préchargement au constructeur de notre BrowserWindow.

Packager et distribuer votre application

Le moyen le plus rapide de distribuer votre nouvelle application est d'utiliser Electron Forge.

info

To build an RPM package for Linux, you will need to install its required system dependencies.

  1. Add a description to your package.json file, otherwise rpmbuild will fail. Blank description are not valid.

  2. Ajoutez Electron Forge en tant que dépendance de développement et utilisez la commande import pour initialiser le squelette de base de Forge.

    npm install --save-dev @electron-forge/cli
    npx electron-forge import

    ✔ Checking your system
    ✔ Initializing Git Repository
    ✔ Writing modified package.json file
    ✔ Installing dependencies
    ✔ Writing modified package.json file
    ✔ Fixing .gitignore

    We have ATTEMPTED to convert your app to be in a format that electron-forge understands.

    Thanks for using "electron-forge"!!!
  3. Créez une distribution en utilisant la commande make de Forge :

    npm run make

    > my-electron-app@1.0.0 make /my-electron-app
    > electron-forge make

    ✔ Checking your system
    ✔ Resolving Forge Config
    We need to package your application before we can make it
    ✔ Preparing to Package Application for arch: x64
    ✔ Preparing native dependencies
    ✔ Packaging Application
    Making for the following targets: zip
    ✔ Making for target: zip - On platform: darwin - For arch: x64

    Electron Forge crée le dossier out où se trouvera votre paquet:

    // Exemple  pour macOS
    out/
    ├── out/make/zip/darwin/x64/my-electron-app-darwin-x64-1.0.0.zip
    ├── ...
    └── out/my-electron-app-darwin-x64/my-electron-app.app/Contents/MacOS/my-electron-app