Nous allons voir dans ce tutoriel comment créer une application de bureau avec le framework Electron. Cet environnement de programmation permet de développer des IHM à l’aide des langages Web JavaScript, HTML et CSS compatible sur plusieurs OS.
Mise en place de l’environnement de programmation
Pour ce tutoriel, nous utilisons l’éditeur de code VS Code.
Le framework Electron fonctionne avec le logiciel Node.js. Téléchargez et installez la dernière version
ou entrez les commandes suivantes sur Linux
sudo apt-get install nodejs npm
Vérifier les versions installées. Cela vous servira pour la compatibilité des librairies
node -v
npm -v
Dans le terminal de VSCode, créer votre répertoire de travail
mkdir ElectronApp && cd ElectronApp
Dans le répertoire de l’application, entrer la commande d’initialisation pour créer les fichiers par défaut
npm init
Entrez les informations demandées. Notez que Electron prend le fichier main.js en point d’entrée (entry point).
Press ^C at any time to quit.
package name: (electronapp)
version: (1.0.0)
description: custom electron app for dev and tutorials
entry point: (index.js) main.js
test command:
git repository:
keywords:
author: aranacorp
license: (ISC) MIT
About to write to D:\Formation\Javascript\Electron\ElectronApp\package.json:
{
"name": "electronapp",
"version": "1.0.0",
"description": "custom electron app for dev and tutorials",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "electron ."
},
"author": "aranacorp",
"license": "MIT"
}
Vous pouvez ensuite installer le paquet electron
npm install --save-dev electron
Une fois le fichier package.json créé, ajouter la ligne suivante dans scripts
"start": "electron ."
Ce scirpt permet de lancer l’application à l’aide la commande
npm start
Création de la première application Electron
Dans cet exemple, nous allons récupérer les versions de node et electron comme dans le tutoriel de base. Nous allons également ajouter un champ de saisie pour définir une éventuelle URL.
Pour créer l’application, nous allons créer 5 fichiers
- main.js gère le cycle de vie de l’application
- index.html contient la page HTML
- ./src/ac_style.css contient le style de la page HTML
- preload.js contient le script de préchargement, notamment les fonctions de communication inter-processus
- renderer.js contient les fonctions qui gère la page HTML
- main.js
const { app, BrowserWindow, ipcMain } = require('electron') const path = require('node:path') const createWindow = () => { const win = new BrowserWindow({ width: 800, height: 600, //icon:'./src/logo_araignee.png', webPreferences: { preload: path.join(__dirname, 'preload.js') } }) ipcMain.on('set-url', (event, url) => { console.log("url set to: ",url) }) //win.webContents.openDevTools() //Open devtools on launch win.setTitle(app.getName()+"@"+app.getVersion()); win.loadFile('index.html') } app.whenReady().then(() => { createWindow() app.on('activate', () => { //for macOS if (BrowserWindow.getAllWindows().length === 0) createWindow() }) }) app.on('window-all-closed', () => { if (process.platform !== 'darwin') app.quit() })
- 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'"> <link rel="stylesheet" href="./src/ac_style.css"> </head> <body> <h1>Hello World!</h1> <p>Nous utilisons les versions: </p> <ul> <li>Node.js : <span id="node-version"></span></li> <li>Chromium : <span id="chrome-version"></span></li> <li>Electron : <span id="electron-version"></span></li> </ul> <p>CurrentURL: <span id="current-url">None</span></p> <p>URL: <input id="url"/> <button id="btn" type="button">Set</button></p> <script src="./renderer.js"></script> </body> </html>
- ./src/ac_style.css
:root { --bg-color: #161616; --btn-color: #346751; --title-color: #3aaa35; /*#c84b31; #ff9900*/ --text-color: #ecdbba; } body { background-color: var(--bg-color); color: var(--text-color); font-family: Arial, sans-serif; margin: 0; padding: 0; } h1 { color: var(--title-color); } p { font-size: 18px; margin-bottom: 20px; }
- preload.js
const { contextBridge, ipcRenderer } = require('electron') contextBridge.exposeInMainWorld('electronAPI', { setURL: (url) => ipcRenderer.send('set-url', url) }) 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]) } })
- renderer.js
const urlInput = document.getElementById('url') const currURL = document.getElementById('current-url') const setButton = document.getElementById('btn') setButton.addEventListener('click', () => { const url = urlInput.value window.electronAPI.setURL(url) currURL.innerHTML = url })
Résultat
Une fois le script lancé à l’aide de « npm start », une fenêtre s’ouvre. Vous pouvez mettre à jour l’URL à l’aide du champ de saisie et du bouton « Set ».
Créer un exécutable pour l’application
Pour créer l’exécutable nous utilisons le paquet electron-packager
npm install --save-dev electron-packager
Vous pouvez ensuite compiler votre projet à l’aide de la commande
npx electron-packager <sourcedir> <appname> --platform=<platform> --arch=<arch> [optional flags...]
Exemple pour Windows
npx electron-packager . myElectronApp --overwrite --asar --platform=win32 --arch=x64 --icon=./src/logo_araignee.ico --prune=true --out=release-builds
Exemple pour Linux
npx electron-packager . myElectronApp --overwrite --asar --platform=linux --arch=x64 --icon=./src/logo_araignee.ico --prune=true --out=release-builds
OS | platform | architecture |
Windows | win32 | x86, x86_64, and arm64 |
Linux | linux | x86, x86_64, armv7l, arm64, and mips64el |
macOS | darwin | x86_64, arm64, and universal |
Dans le fichier package.json, ajoutez ces deux scripts comme raccourcis;
"build": "electron-packager . myElectronApp --overwrite",
"clean": "rm -rf release-builds"
Vous pouvez créer un exécutable avec la commande
npm run build
ou effacer les dossiers générés avec
npm run clean
Vous pouvez maintenant lancer l’application à partir du fichier exécutable myElectronApp.exe
Bonus: Créer une application avec Electron et React
Nous allons créer la même application avec Electron et React. Pour cela, nous créons un nouveau projet
npm init electron-app@latest react-electron-app -- --template=webpack
cd react-electron-app
npm install --save-dev @babel/core @babel/preset-react babel-loader
Modifiez ensuite le fichier webpack.rules.js
{ test: /\.jsx?$/, use: { loader: 'babel-loader', options: { exclude: /node_modules/, presets: ['@babel/preset-react'] } } }
npm install –save react react-dom
- index.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Hello World!</title> </head> <body> <div id="root"></div> </body> </html>
- renderer.js
import React from "react"; import ReactDOM from "react-dom/client"; import "./index.css"; import App from "./app.jsx"; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <React.StrictMode> <App /> </React.StrictMode> );
- app.jsx
import React from "react"; class App extends React.Component { constructor(props) { super(props); this.state = { url: "None", }; } setUrl = () => { //() => {this.setState({url: document.getElementById("url").value})} this.setState({url: document.getElementById("url").value}) } render() { return ( <div> <h1>Hello World!</h1> <p>Welcome to your Electron application.</p> <p>CurrentURL: <span id="current-url">{this.state.url}</span></p> <p>URL: <input id="url" /> <button id="btn" type="button" onClick={this.setUrl}>Set</button></p> </div> ); } } export default App;
Vous pouvez ensuite lancer l’application avec la commande
npm start
Pour créer l’exécutable
npm run make