Come risolvere il bug di nw-gyp: guida pratica per NW.js 0.101.2

Come risolvere il bug di nw-gyp: guida pratica per NW.js 0.101.2

NW.js è una piattaforma fantastica per creare applicazioni desktop con tecnologie web. Ma chi ha provato a compilare moduli nativi con nw-gyp sulla versione 0.101.2 (e non solo con tale versione!) sa bene che… qualcosa non torna. In questa guida ti spiego come risolvere il bug che impedisce la compilazione corretta e ti mostro come creare un modulo nativo compatibile con NW.js su Windows 64 bit.

Situazione ipotetica di partenza

Ipotizziamo di voler creare un modulo nativo che si occupi di fare alcune query critiche sulla nostra base dati. Ipotizziamo anche di posizionare tale modulo nativo nella cartella src/napi/limit.cpp.
Per poterlo compilare abbiamo bisogno di installare le node-addon-api. Quindi digitiamo il comando:

npm install node-addon-api 

E ci serve anche nw-gyp che però non è aggiornato da tempo e, in fase di installazione, ci fornirà diversi warning sulla sicurezza. Il comando è il seguente:

npm install --save-dev nw-gyp

Adesso dobbiamo creare il file binding.gyp. Ipotizziamo di posizionare tale file all’interno della stessa cartella del file limit.cpp.
Una volta preparato il codice di entrambi i file, siamo pronti alla compilazione.
Qui servono alcune premesse, in particolare bisogna assicurarsi di avere la versione NW.js e la versione Node.js compatibili. Ad esempio, la versione 0.101.2 di NW.js vuole la versione 20.9.0 di Node. Questa verifica è fondamentale!
Adesso ci rechiamo nella cartella src/napi e proviamo a compilare il nostro modulo nativo limit.cpp. Primo comando de eseguire:

npx nw-gyp configure --target=0.101.2

Non dovrebbe dare problemi. Poi però ci tocca il comando:

npx nw-gyp build

E qui viene fuori il bug della versione non riconosciuta!

Il problema: nw-gyp non riconosce la versione

Quando provi a compilare un modulo nativo (come limit.node) usando nw-gyp, utilizzando il comando npx nw-gyp build, ottieni un errore simile a:

gyp info it worked if it ends with ok gyp info using nw-gyp@3.6.8 gyp info using node@20.9.0 | win32 | x64 gyp 
ERR! UNCAUGHT EXCEPTION 
gyp ERR! stack TypeError: Invalid Version: undefined 
gyp ERR! stack at new SemVer (...)
...
gyp ERR! This is a bug in `nw-gyp`. 
gyp ERR! Try to update nw-gyp and file an Issue if it does not help: 
gyp ERR! <https://github.com/nwjs/nw-gyp/issues>

Questo accade perché nw-gyp cerca un file version che non esiste nella struttura delle release di NW.js. Il bug è noto, ma non ancora risolto ufficialmente.

La soluzione: patch manuale a nw-process-release.js

Il file incriminato è questo:

node_modules/nw-gyp/lib/nw-process-release.js

Intervento chirurgico

Apri il file e cerca questa riga (si dovrebbe trovare tra le prime righe del file):

var version = (semver.valid(argv[0]) && argv[0]) || gyp.opts.target || process.env.npm_config_target 

Sostituiscila con:

var version = (semver.valid(argv[0]) && argv[0]) || gyp.opts.target || process.env.npm_config_target  || '0.101.2'

Facendo attenzione che la versione di NW indicata sia esattamente quella utilizzata! Questo forza nw-gyp a usare la versione corretta per la compilazione. A questo punto prova ad eseguire la compilazione. Se tutto fila liscio, all’interno della cartella src/napi/ verrà creata la cartella build e, al suo interno, la cartella Release. In quest’ultima cartella dovremmo trovare il nostro file limit.node.

Test: compilare limit.node

Riepilogando, per verificare che tutto funzioni, prova a compilare un modulo semplice come limit. Ecco i passaggi:

  1. Installa le api node: npm install node-addon-api
  2. Installa nw-gyp localmente: npm install --save-dev nw-gyp
  3. Applica la patch come descritto sopra
  4. Compila il modulo: prima npx nw-gyp configure --target=0.101.2 e poi npx nw-gyp build
  5. Copia il file .node nella cartella node_modules/limit/build/Release/
  6. Avvia la tua app NW.js e verifica che il modulo venga caricato correttamente.

Attenzione! Il file JavaScript che richiama il modulo nativo appena compilato deve essere eseguito nel contesto di Node e non in quello del browser. Quindi, se ad esempio il nostro file JavaScript si chiama native-loder.js, allora deve essere caricato come segue (da notare l’attributo node):

<script src="src/scripts/native-loader.js" node></script>

Bonus: usa NWjs Builder

Se vuoi semplificarti la vita durante la distribuzione del tuo progetto NW.js, ho creato un’applicazione grafica che ti aiuta a farlo. In particolare ti consente di:

  • Selezionare la versione di NW.js con cui distribuire il progetto
  • Scegliere l’icona da assegnare al file eseguibile che verrà creato
  • Compilare il progetto, solo per Windows a 64bit, con un click.

Scopri NWjs Builder sul mio blog

Conclusione

Questo workaround ti permette di continuare a usare NW.js anche con moduli nativi, in attesa che il bug venga risolto ufficialmente. Se ti è stato utile, condividilo con altri sviluppatori: la community cresce grazie a chi condivide! Il lavoro qui svolto è stato possibile grazie all’aiuto di Copilot che però non è autorizzato a diffondere il contenuto delle chat private. Per questo motivo abbiamo scritto questo articolo “a 4 mani” e lo abbiamo condiviso. In questo modo, essendo un post pubblico, Copilot lo potrà utilizzare per aiutare altri programmatori che gli chiederanno aiuto su questo specifico argomento.

Hai trovato altri workaround o soluzioni? Scrivimi nei commenti o contattami su GitHub — mi fa sempre piacere confrontarmi!

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *