Questa guida assume che si conoscano i frameworks ElctronJs e React, che si abbia installato nel proprio computer NodeJs e che si possa utilizzare npm o yarn ed npx. Lo scopo è quello di utilizzare Electron per realizzare applicazioni cross platform fruttando lo sviluppo web tramite React, così da rendere il tutto più strutturato e modulare.
Purtroppo questi due framework di sviluppo non sono nativamente comunicanti tra loro, ma essendo uno – Electron – un generatore di pagine che sfrutta Chromium per la renderizzazione e l’altro – React – un framework per lo sviluppo UI, diciamo che con poco lavoro riusciremo a far comunicare entrambe le parti.
Attualmente le versioni dei framework e software che andrò ad utilizzare sono i seguenti:
- node 12.18.3
- npm 6.14.8
- React 17.0.1
- Electron 11.0.3
Creare una React app
Per prima cosa, partiremo dalla creazione di una nuova React app, così da avere l’intero progetto.
$ npx create-react-app <app-name>
Nel mio caso ho realizzato la mia React app dal nome maggioli ed il risultato è il seguente

Adesso con il nostro IDE preferito, apriamo il progetto. (Io utilizzo VSCode, ma qualsiasi editor va benissimo lo stesso)
Per evitare conflitti o malfunzionamenti causati dalle più recenti versioni di Electron, installeremo anche il supporto a Typescript.
Dirigiamoci nella root del progetto e lanciamo npm install typescript
$ cd <app-name>
$ npm install typescript
Al termine delle operazioni dovremmo avere una situazione come questa in foto

Arrivati a questo punto, abbiamo la nostra applicazione basica di React e non ci resta che farla girare sotto Electron, quindi per prima cosa installiamo qualche modulo che ci tornerà comodo:
$ npm install --save cross-env electron-is-dev
Nota: cross-env lo utilizzeremo per impostare da comando la variabile d’ambiente BROWSER=none evitando la normale apertura del browser all’avvio dell’applicazione React.
electron-is-dev è un modulo che da la possibilità di utilizzare le funzioni di debug esclusivamente su ambiente di test o sviluppo
A scaricamento completato, terminiamo la nostra installazione dei moduli aggiungendo ora electron ed electron-builder
$ npm install concurrently wait-on
$ npm install electron --save-dev
$ npm install electron-builder --save-dev
Nota: concurrently ci da la possibilità di eseguire più applicazioni node simultaneamente, mentre wait-on è un modulo che ci permetterà letteralmente di “attendere” una risposta.
Bene! Adesso abbiamo tutto il necessario per lanciare il nostro progetto. Purtroppo per noi però, la cosa non è proprio finita qui.
Infatti adesso dovremmo integrare React in Electron, attraverso pochi e semplici step.
Step 1: Generare il file electron.js
Nella cartella del nostro progetto, creiamo un file chiamato electron.js e posizioniamolo all’interno della cartella ./public
const electron = require("electron");
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
const path = require("path");
const isDev = require("electron-is-dev");
let mainWindow;
const createWindow = () => {
mainWindow = new BrowserWindow({
width: 900,
height: 680
});
/**
* Controllo di versione
*/
mainWindow.loadURL(
isDev ? "http://localhost:3000" : `file://${path.join(__dirname, "../build/index.html")}`
);
mainWindow.on("closed", () => (
mainWindow = null
))
}
app.on("ready", createWindow)
app.on("window-all-closed", () => {
process.platform !== "darwin" && app.quit()
})
app.on("activate", () => {
mainWindow === null && createWindow()
})
Step 2: Modifica del file package.json
Ora non ci resta che modificare il file package.json in modo da eseguire sia gli script di React, che quelli di Electron.
Andremo ad aggiungere delle definizioni che servono esclusivamente ad Electron in fase di build ed i relativi comandi di start/build/etc con l’ingresso del nuovo main file che abbiamo appena creato.
"name": "maggioli",
"version": "0.1.0",
"private": true,
"author": {
"name": "Stefano Pascazi",
"email": "stefano.pascazi@maggioli.it",
"url": "https://www.stefanopascazi.com"
},
"build": {
"appId": "com.maggioli"
},
"main": "public/electron.js",
Ed aggiungiamo i comandi:
"scripts": {
"react:start": "react-scripts start",
"react:build": "react-scripts build",
"react:test": "react-scripts test",
"react:eject": "react-scripts eject",
"electron:build": "electron-builder",
"release": "npm run react:build && npm run electron-builder --publish=always",
"build": "npm run react:build && npm run electron:build",
"start": "concurrently \"cross-env BROWSER=none npm run react:start\" \"wait-on http://localhost:3000 && electron .\""
},
Abbiamo finito! Non ci resta che testare la nostra applicazione.
$ npm start

Oppure se vogliamo fare la nostra build:
$ npm run build
Tips. Come si legge dal package.json, ho lasciato – riscritto in realtà – anche i comandi per interagire con React o Electron singolarmente, in questo modo abbiamo comunque la possibilità di visualizzare la nostra React app via browser o di eseguire delle build di Test.
4 Comments
Danilo
Ciao e grazie mille per questo articolo.
Con estrema semplicità hai spiegato come integrare una applicazione react in electron.
Ci sono numerosi tutorial che spiegano come fare ma sono molto più complessi e non arrivano direttamente al punto come hai fatto tu con questo articolo.
Ne approfitto per segnalarti che lanciando lo script di build vengono restituiti alcuni errori:
1) nello script “build”: “npm run react-build && npm run electron:build” andrebbe cambiato il nome dello script react-build che viene richiamato in react:build altrimenti non lo trova
2) Mi compaiono in oltre questi due errori:
Package “electron” is only allowed in “devDependencies”. Please remove it from the “dependencies” section in your package.json.
Package “electron-builder” is only allowed in “devDependencies”. Please remove it from the “dependencies” section in your package.json.
Ho risolto spostando quei package nella sezione devDependencies
Nonostante la build arrivi fino in fondo quando avvio il .exe mi si apre la finestra di electron ma senza nessun contenuto.
Guardando nel developer tool trovo questo messaggio di errore:
You need to enable JavaScript to run this app.
e nella console questi errori:
main.8c8b27cf.chunk.css:1 Failed to load resource: net::ERR_FILE_NOT_FOUND
2.0ded619b.chunk.js:1 Failed to load resource: net::ERR_FILE_NOT_FOUND
main.499a87ed.chunk.js:1 Failed to load resource: net::ERR_FILE_NOT_FOUND
Hai una idea di come sistemare?
Grazie mille,
Danilo.
Stefano Pascazi
Ciao Danilo e grazie per il tuo feedback. Mi fa davvero piacere.
Il comando di build, è un mio refuso che ti ringrazio di avermi segnalato.
I file packages di electron per essere buildati nella maniera corretta devono essere posizionati in devDependencies come segnalato da node durante la tua build, quindi hai fatto benissimo a correggere.
Per quanto riguarda la build che non ti trova i file compilati in js di react è molto importante stare attenti a due semplici passaggi:
1) Che il comando di build rispetti la compilazione prima di react e successivamente di electron: “npm run react:build && npm run electron:build”
2) Che tu abbia indicato correttamente la condizione nel file electron.js nella cartella public:
/**
* Controllo di versione
*/
mainWindow.loadURL(
isDev ? "http://localhost:3000" : `file://${path.join(__dirname, "../build/index.html")}`
);
In ultimo, di effettuare un controllo sul tipo di versione che hai durante la build.
Nel caso, puoi impostarti un file .env in cui indichi la versione development o production a seconda dei casi.
Fammi sapere se risolvi.
Ciao.
Stefano
Ciao,
Intanto complimenti per la guida, davvero utile.
Mi ritrovo però con lo stesso errore di Danilo e non credo che sia un discorso di variabili d’ambiente.
Infatti il problema è proprio nel caso: `file://${path.join(__dirname, “../build/index.html”)}`
Per conferma, ho fatto questi test che mi hanno portato agli stessi errori di “Failed to load resource: net::ERR_FILE_NOT_FOUND”:
– ho aperto direttamente il file “build/index.html”;
– ho scambiato lo statement del caso ELSE con quello IF, quindi facendo aprire “build/index.html” nel caso isDev.
Hai idea di cosa possa trattarsi?
Grazie in anticipo
Stefano
Ciao a tutti,
la soluzione agli errori “Failed to load resource: net::ERR_FILE_NOT_FOUND” è inserire nel package.json la seguente riga:
“homepage”: “.”,
In questo modo nella folder “/build” il file index.html risolve tutti i file mancanti e lo stesso succede lanciando l’app dal file .exe dentro la folder “/dist”.
Un saluto,
Stefano