00
:
00
:
00
:
00
Corso SEO AI - Usa SEOEMAIL al checkout per il 30% di sconto

Struttura di un Progetto Electron

Una buona struttura del progetto è fondamentale per mantenere il codice organizzato e scalabile. Electron non impone una struttura rigida, ma ci sono convenzioni consolidate dalla community.

Struttura Base

Un progetto Electron minimale ha questa struttura:

mia-app/
├── package.json          # Configurazione e dipendenze
├── main.js               # Entry point - Main Process
├── preload.js            # Script di preload
├── index.html            # Pagina principale
├── renderer.js           # Logica del renderer
└── styles.css            # Stili

Struttura Consigliata per Progetti Reali

Per applicazioni più complesse, è consigliato separare il codice per responsabilità:

mia-app/
├── package.json
├── forge.config.js       # Configurazione Electron Forge
│
├── src/
│   ├── main/             # Codice del Main Process
│   │   ├── main.js       # Entry point principale
│   │   ├── menu.js       # Menu dell'applicazione
│   │   ├── tray.js       # System tray
│   │   ├── ipc.js        # Handler IPC
│   │   └── updater.js    # Auto-updater
│   │
│   ├── preload/          # Preload scripts
│   │   └── preload.js    # Bridge tra main e renderer
│   │
│   ├── renderer/         # Codice del Renderer Process
│   │   ├── index.html    # Pagina principale
│   │   ├── app.js        # Logica applicazione
│   │   ├── styles.css    # Stili
│   │   └── pages/        # Pagine aggiuntive
│   │       ├── settings.html
│   │       └── about.html
│   │
│   └── shared/           # Codice condiviso
│       ├── constants.js  # Costanti condivise
│       └── utils.js      # Utility condivise
│
├── assets/               # Risorse statiche
│   ├── icons/            # Icone dell'app
│   │   ├── icon.png
│   │   ├── icon.ico
│   │   └── icon.icns
│   └── images/           # Altre immagini
│
├── dist/                 # File compilati (generato)
└── out/                  # Pacchetti distribuibili (generato)

Ruolo di Ogni Cartella

src/main/

Contiene tutto il codice che gira nel Main Process. Qui hai accesso completo alle API di Node.js e alle API native di Electron:

// src/main/main.js
const { app, BrowserWindow } = require('electron');
const path = require('node:path');
const { setupMenu } = require('./menu');
const { setupIPC } = require('./ipc');

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

  mainWindow.loadFile(
    path.join(__dirname, '..', 'renderer', 'index.html')
  );

  return mainWindow;
}

app.whenReady().then(() => {
  const mainWindow = createWindow();
  setupMenu(mainWindow);
  setupIPC(mainWindow);
});

src/preload/

Contiene i preload script che fungono da ponte sicuro tra Main Process e Renderer Process:

// src/preload/preload.js
const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('electronAPI', {
  openFile: () => ipcRenderer.invoke('dialog:openFile'),
  saveFile: (data) => ipcRenderer.invoke('dialog:saveFile', data),
  onUpdateAvailable: (callback) =>
    ipcRenderer.on('update-available', callback),
});

src/renderer/

Contiene tutto il codice dell’interfaccia utente. Qui scrivi HTML, CSS e JavaScript come in un’applicazione web tradizionale:

<!-- src/renderer/index.html -->
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta http-equiv="Content-Security-Policy"
        content="default-src 'self'; script-src 'self'">
  <title>La Mia App</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <div id="app">
    <nav id="sidebar"><!-- Navigazione --></nav>
    <main id="content"><!-- Contenuto --></main>
  </div>
  <script src="app.js"></script>
</body>
</html>

src/shared/

Codice e costanti condivise tra Main e Renderer Process:

// src/shared/constants.js
module.exports = {
  IPC_CHANNELS: {
    OPEN_FILE: 'dialog:openFile',
    SAVE_FILE: 'dialog:saveFile',
    GET_SETTINGS: 'settings:get',
    SET_SETTINGS: 'settings:set',
  },
  APP_NAME: 'La Mia App',
  DEFAULT_WINDOW_SIZE: { width: 1200, height: 800 },
};

assets/

Risorse statiche come icone, immagini e font. Le icone dell’applicazione devono essere nei formati corretti per ogni piattaforma:

  • Windows: .ico (256x256)
  • macOS: .icns
  • Linux: .png (512x512)

Configurazione del package.json

Il package.json deve puntare all’entry point corretto:

{
  "name": "mia-app",
  "version": "1.0.0",
  "main": "src/main/main.js",
  "scripts": {
    "start": "electron .",
    "build": "electron-forge make",
    "package": "electron-forge package"
  },
  "devDependencies": {
    "electron": "^33.0.0"
  }
}

Struttura con Framework Frontend

Se usi un framework come React, Vue o Svelte per il renderer, la struttura si adatta:

mia-app/
├── package.json
├── vite.config.js        # Bundler per il renderer
│
├── src/
│   ├── main/             # Main Process (invariato)
│   │   └── main.js
│   │
│   ├── preload/          # Preload (invariato)
│   │   └── preload.js
│   │
│   └── renderer/         # Ora con framework
│       ├── index.html
│       ├── App.jsx       # Componente root React/Vue/etc
│       ├── main.jsx      # Entry point del framework
│       └── components/   # Componenti UI
│
└── electron-builder.yml  # Config distribuzione

Best Practice

  1. Separare i processi: Mai mischiare codice Main e Renderer nella stessa cartella
  2. Centralizzare le costanti IPC: Usare shared/constants.js per i nomi dei canali IPC evita errori di digitazione
  3. Un file per responsabilità: Separare menu, tray, IPC handlers e updater in file dedicati
  4. Assets organizzati: Tenere le icone separate dalle immagini dell’app
  5. Ignorare le cartelle generate: Aggiungere dist/ e out/ al .gitignore