Come strutturare un’applicazione: creazione ed esportazione dei moduli

Come organizzare la propria applicazione Node.JS attraverso l'utilizzo di una architettura modulare.

Utilizzo del modulo

Il modulo realizzato a pagina precedente è pronto ad essere utilizzato. Trattandosi di una libreria, chiaramente non possiamo eseguirlo da solo. In altre parole non ha senso eseguire il comando “node module_01.js”. Sarà un’altra applicazione ad includere il modulo, attraverso la normale istruzione require, e poi invocarne i metodi esposti.
Prima di vedere il codice dell’applicazione che utilizza il modulo, approfondiamo alcuni aspetti dell’istruzione require. Nelle elezioni precedenti abbiamo usato l’istruzione esclusivamente per caricare moduli del core, passando per argomento parole chiave come “http”, “url”, “net”, ecc. Adesso vogliamo usare la stessa istruzione per caricare il nostro modulo. Una domanda sensata potrebbe essere: come fa Node.js a distinguere tra un modulo del core e un nostro modulo personalizzato?

La risposta è la seguente: se l’argomento della funzione require è una normale stringa, l’interprete di Node.js assumerà che stiamo cercando di caricare un modulo del core. Se invece l’argomento inizia con un path, ad esempio perché il primo carattere è un puntino (“.”) oppure uno slash (“/”), l’interprete andrà a cercare nel file system la risorsa passata come argomento. Tale ricerca inizierà dalla directory dove si trova l’applicazione, per cui possiamo usare sia percorsi relativi che assoluti. Se il file non viene trovato, l’interprete di Node.js potrebbe cercare comunque tra i moduli del core, perciò è bene ricordarsi che essi si trovano nella directory node_modules. Infine, se anche qui non viene trovato il nostro modulo, Node.js proverà a cercare tenendo conto della variabile di sistema $NODE_PATH.

Siamo finalmente pronti a vedere il codice dell’applicazione che utilizza il nostro modulo:

Come promesso, basta usare l’istruzione require per caricare il modulo. Se proviamo a “scommentare” l’ultima riga, otterremo un errore durante l’esecuzione dello script. Questo perché la funzione parse() è privata, quindi non può essere invocata esternamente al modulo. Se volessimo rendere pubblica tale funzione basterebbe editare il contenuto del modulo (il file “module_01.js” e aggiungere istruzione di export anche per essa, ovvero

ovviamente possiamo scegliere, come nome logico (il metodo esposto nelle API), anche lo stesso nome della funzione com’è definita nel modulo.

L’esempio mostra come sia semplice costruire dei nuovi moduli, realizzando un insieme di librerie personalizzate, che permettono di centralizzare le funzioni e/o la logica che potrebbe essere riusata, sia da altri progetti, sia dallo stesso progetto. Questa è una pratica da tenere in considerazione anche se non non ci viene richiesto esplicitamente un’architettura modulare, perché è meglio essere lungimiranti piuttosto che dover correre ai ripari in un secondo tempo. In altre parole: meglio prevenire che curare.