Primo Progetto: Hello World
In questa guida costruiremo una semplice applicazione Electron passo dopo passo, partendo da zero fino ad avere una finestra desktop funzionante.
Creazione del Progetto
Inizia creando una nuova cartella e inizializzando il progetto:
mkdir electron-hello-world
cd electron-hello-world
npm init -y
npm install electron --save-dev
File 1: package.json
Modifica il package.json generato:
{
"name": "electron-hello-world",
"version": "1.0.0",
"description": "La mia prima app Electron",
"main": "main.js",
"scripts": {
"start": "electron ."
},
"devDependencies": {
"electron": "^33.0.0"
}
}
File 2: main.js
Crea il file main.js, il cuore dell’applicazione che gestisce il Main Process:
const { app, BrowserWindow } = require('electron');
const path = require('node:path');
// Funzione per creare la finestra principale
function createWindow() {
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
},
});
// Carica il file HTML nella finestra
mainWindow.loadFile('index.html');
}
// Quando Electron è pronto, crea la finestra
app.whenReady().then(() => {
createWindow();
// Su macOS, ricrea la finestra quando si clicca sull'icona del dock
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
});
// Chiudi l'app quando tutte le finestre sono chiuse (eccetto su macOS)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
Spiegazione del codice
app: Controlla il ciclo di vita dell’applicazione (avvio, chiusura, eventi)BrowserWindow: Crea e gestisce le finestre dell’applicazioneapp.whenReady(): Restituisce una Promise risolta quando Electron è completamente inizializzatowindow-all-closed: Su Windows e Linux chiude l’app; su macOS (darwin) le app restano attive nel dockactivate: Su macOS, ricrea la finestra quando l’utente clicca sull’icona nel dock
File 3: preload.js
Il preload script espone in modo sicuro le informazioni di sistema al renderer:
const { contextBridge } = require('electron');
contextBridge.exposeInMainWorld('versions', {
node: () => process.versions.node,
chrome: () => process.versions.chrome,
electron: () => process.versions.electron,
});
File 4: index.html
Crea l’interfaccia utente:
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World - Electron</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container">
<h1>Hello World!</h1>
<p>Benvenuto nella tua prima app Electron</p>
<div class="info-box">
<h2>Informazioni di Sistema</h2>
<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>
</div>
<button id="btn-click">Cliccami!</button>
<p id="click-count">Hai cliccato 0 volte</p>
</div>
<script src="renderer.js"></script>
</body>
</html>
File 5: styles.css
Aggiungi lo stile all’applicazione:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background-color: #1e1e2e;
color: #cdd6f4;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.container {
text-align: center;
padding: 2rem;
}
h1 {
font-size: 3rem;
color: #89b4fa;
margin-bottom: 0.5rem;
}
.info-box {
background-color: #313244;
border-radius: 12px;
padding: 1.5rem;
margin: 2rem 0;
text-align: left;
}
.info-box h2 {
color: #a6e3a1;
margin-bottom: 1rem;
font-size: 1.2rem;
}
.info-box ul {
list-style: none;
}
.info-box li {
padding: 0.3rem 0;
color: #bac2de;
}
.info-box span {
color: #f9e2af;
font-family: monospace;
}
button {
background-color: #89b4fa;
color: #1e1e2e;
border: none;
padding: 0.8rem 2rem;
font-size: 1rem;
border-radius: 8px;
cursor: pointer;
transition: background-color 0.2s;
}
button:hover {
background-color: #74c7ec;
}
#click-count {
margin-top: 1rem;
color: #a6adc8;
}
File 6: renderer.js
Aggiungi la logica dell’interfaccia:
// Mostra le versioni di sistema esposte dal preload
document.getElementById('node-version').textContent =
window.versions.node();
document.getElementById('chrome-version').textContent =
window.versions.chrome();
document.getElementById('electron-version').textContent =
window.versions.electron();
// Gestisci il click del bottone
let clickCount = 0;
const button = document.getElementById('btn-click');
const countDisplay = document.getElementById('click-count');
button.addEventListener('click', () => {
clickCount++;
countDisplay.textContent = `Hai cliccato ${clickCount} volt${clickCount === 1 ? 'a' : 'e'}`;
});
Avviare l’Applicazione
Ora la struttura del progetto è:
electron-hello-world/
├── package.json
├── main.js
├── preload.js
├── index.html
├── styles.css
└── renderer.js
Avvia l’applicazione:
npm start
Si aprirà una finestra desktop con il messaggio “Hello World!”, le informazioni di sistema e un bottone interattivo.
Prossimi Passi
Ora che hai la tua prima app Electron funzionante, puoi:
- Esplorare l’architettura Main/Renderer Process in dettaglio
- Imparare la comunicazione IPC tra i processi
- Aggiungere menu nativi e funzionalità di sistema
- Integrare un framework frontend come React o Vue