Questo post fa parte di una serie dedicata ad Aurelia e ASP.NET Core.
Nel precedente post ci siamo lasciati parlando di un nuovo approccio per la gestione delle dipendenze lato client: non più NuGet (che rimane lo strumento ideale per la gestione di quelle lato server e anzi risulta notevolmente potenziato dall’approccio a pacchetti intrinseco nel framework .NET Core stesso) ma NPM. Anzi no, Bower.
Cosa sono NPM e Bower?
Anche se vi sembra di averci capito poco, in realtà la confusione è solo teorica. Non vi preoccupate, avrà modo di diventare pratica nel corso di questo post.
Abbiamo già detto che NPM è l’acronimo di Node Package Manager, cioè l’equivalente NuGet per il mondo Node.js.
Cosa c’è che non va con NuGet? Perché cambiare? Per diversi motivi, meravigliosamente espressi da Gianluca Carucci nella sua sessione dello scorso anno ai Community Days. In breve:
- mischiare dipendenze lato client e lato server nello stesso strumento contribuisce a creare un’entropia che è crescente all’aumentare delle dimensioni e della complessità del progetto;
- i pacchetti NuGet delle librerie client-side non sono sempre “ufficiali” e sono comunque il porting degli equivalenti pacchetti Node.js, quindi ha molto più senso andare direttamente alla fonte per ottenere le risorse più aggiornate e consistenti;
- usando NuGet una serie di fondamentali operazioni – come ad esempio Bundling e Minification, o la trasformazione di file Less in CSS – devono essere svolte con strumenti dedicati di .NET o di Visual Studio che potrebbero non essere disponibili in altri contesti (ricordiamoci sempre che ASP.NET Core è multi-piattaforma).
Ok, abbiamo capito (forse) che affiancare NPM a NuGet può essere una buona idea. Ma perché allora Visual Studio ci suggerisce di usare Bower per installare jQuery? Per capirlo (forse) non dobbiamo dimenticare che Node è un framework per la realizzazione di applicazioni web in JavaScript. In quanto tale, un progetto Node avrà tipicamente bisogno sia delle risorse da utilizzare sul server che di quelle da consumare sul client. Per quanto attiene al codice, tali risorse saranno JavaScript in entrambi i casi, ma per il resto la dicotomia è la stessa che abbiamo appena descritto per i progetti ASP.NET e anche la confusione potrebbe essere la stessa.
E allora se NuGet e NPM sono package manager da utilizzare per gestire le dipendenze lato server (rispettivamente in un progetto ASP.NET e Node), è bene usare qualcosa di specifico – nella fattispecie Bower – per gestire quelle lato client. Bower è un package disponibile su NPM (quindi può essere scaricato e aggiunto al progetto usando NPM) ed è a sua volta un package manager espressamente dedicato alla gestione di risorse lato client – con tutte le loro specificità – che in un progetto web sono tipicamente HTML, CSS, JavaScript. Vista la strada intrapresa da Microsoft per ASP.NET Core, non sorprende che il supporto tanto per NPM quanto per Bower sia decisamente buono in Visual Studio e questo ci semplificherà il compito se non siamo amanti della riga di comando.
A questo punto sembrerebbe tutto chiaro: per procedere nel nostro cammino prima aggiungiamo NPM al nostro progetto ASP.NET Core, quindi lo usiamo per aggiungere Bower, infine usiamo quest’ultimo per installare i package relativi ad Aurelia: il gioco è fatto.
Il terzo incomodo: JSPM
In realtà seguiremo (almeno inizialmente) un percorso leggermente diverso, per rimanere più aderenti all’approccio utilizzato dal team di Aurelia. E qui comincia la parte pratica della confusione.
Il team ho scelto infatti di basare lo sviluppo del framework non su Bower ma su JSPM che altri non è se non “yet another package manager” con qualcosa in più.
Un altro? Sì, un altro! Come mi ha fatto notare Nicolò durante il viaggio verso Future Decoded, usare JavaScript nel 2016 può essere una questione non propriamente immediata da approcciare. Il paradiso dei Geek può rapidamente trasformarsi in un inferno per un “ingenuo” programmatore web che magari proviene da un background ASP.NET. D’altra parte è abbastanza naturale che in un ambiente in cui domina l’open source ogni mattina qualcuno si svegli con in testa “il” nuovo framework che rivoluzionerà (in meglio) il modo di sviluppare software sul pianeta, o anche soltanto con un fork di un framework esistente per meglio adattarlo alle proprie esigenze. I package manager, con la loro pesante influenza sul modo in cui il progetto viene progettato e strutturato, non sfuggono a questa logica.
In definitiva non abbiamo fatto in tempo a scoprire che esiste un package manager specifico per JavaScript, che subito dobbiamo affrontare il fatto che ne esistono in realtà molteplici, ciascuno con caratteristiche leggermente diverse. Tra questi, come detto, il team di Aurelia ha deciso di preferire JSPM.
Visto che non vogliamo deviare troppo dalla nostra rotta, mi limito a dire che JSPM combina le caratteristiche classiche di un package manager (tipo Bower) con l’infrastruttura di caricamento modulare (che permette di caricare i file JavaScript dinamicamente man mano che sono necessari) e con le funzionalità di transpling (che consentono a moduli scritti in ES2015 nativo di essere “convertiti” dietro le quinte in codice JavaScript compatibile con i browser che non lo supportano). In particolare, JSPM usa SystemJS come module loader universale: in questa maniera è possibile caricare moduli di diversi formati (ES2015, AMD, CommonJS, …) da diverse fonti (NPM, GitHub, …). In fase di sviluppo i diversi moduli sono caricati come file separati in modalità asincrona, per il passaggio in produzione è invece possibile ottimizzarli in uno o più bundle con un semplice comando.
La scelta del team non è vincolante: Aurelia è disponibile anche come pacchetto Bower, ed è provvisto anche di un buon supporto per webpack; tuttavia in una prima fase useremo l’approccio consigliato per non mettere troppa carne al fuoco (cosa che nella vita reale mi piace invece fare parecchio).
Happy coding!