Introduzione a NodeJs
Cosa è NodeJs
NodeJs è un runtime che consente di eseguire applicazioni scritte in Javascript su qualsiasi macchina, estendendo quindi la possibilità di scrivere applicazioni in questo linguaggio al di fuori del browser.
Il motore di esecuzione di NodeJS è Google V8, lo stesso utilizzato per il browser Chrome.
NodeJs è utilizzato nello specifico per realizzare siti web, web services, applicazioni desktop, applicazioni di IoT e di Intelligenza Artificiale, ed infine come strumento a supporto dello sviluppo di altri linguaggi, in particolare nella realizzazione di applicazioni mobile (grazie a framework come Cordova e Ionic).
Grazie al fatto che Javascript è il linguaggio di programmazione più utilizzato al mondo NodeJs ha avuto una enorme diffusione.
NodeJs è una applicazione installabile nella maggior parte dei sistemi operativi, e si può scaricare da qui.
Il mio primo progetto Node
Le applicazioni NodeJS possono essere scritte su qualsiasi IDE, ma si consiglia l’utilizzo di Visual Studio Code, visto che è studiato per scrivere codice Javascript, ed è stato scritto proprio con NodeJS.
Quindi dopo essere entrati in VS Code, esserci posizionati su una nuova cartella, occorre aprire il terminale e scrivere
npm init
Cos’è npm? NodeJs introduce il concetto di package manager, ovvero una applicazione che permette di gestire un progetto NodeJS (o anche Javascript per browser), L’applicazione si chiama npm (Node Package Manager) e permette di svolgere le seguenti attività:
- gestire un file di configurazione che contiene i metadati del progetto, chiamato
package.json
; - scaricare e tenere traccia nel file di configurazione di librerie presenti nel catalogo ufficiale (npmjs.com) che vedremo sotto.
- gestire comandi per eseguire il codice Node, fare test, o altre operazioni di DevOps.
Un file package.json
èo quindi il documento di configurazione principale di progetto di una applicazione NodeJs.
Qui un esempio di package.json.
{
"name": "Hello World",
"version": "1.0.0",
"description": "simple Hello World application",
"main": "index.js",
"author": "cipiaceinfo.it",
"license": "ISC",
"dependencies": {
}
}
A questo punto creiamo il file index.js e scriviamo
console.log("Hello World").
Ed eseguiamo da linea di comando:
>node index.js
Hello World
Come si può vedere console.log (o info, error, ecc.) stampa su terminale.
C’è un altro modo in VS Code per eseguire il codice NodeJS: posizionandosi sul pulsante

ed eseguendo il codice dello script correntemente selezionato. Maggiori dettagli sul sito di NodeJs.
Ambienti di sviluppo
In locale: Visual Studio Code
Visual Studio Code è una applicazione IDE (ambiente integrato di sviluppo) compatibile con la maggior parte dei linguaggi di programmazione. E’ disponibile per Linux, MacOS e Windows. Visual Studio Code è preconfigurato per scrivere applicazioni Web Javascript. .
Una volta installato e configurato l’ambiente si ha a disposizione l’ambiente IDE di sviluppo.
Online
Online sono disponibili diversi ambienti di sviluppo, quasi tutti basati su una versione online di VS Code. L’ambiente qui consigliato è Stackblitz.
Stackblitz offre un ambiente NodeJS (e frontend) completo.
Librerie esterne
In Node non sono presenti gli oggetti presenti nel browser, quindi niente DOM e BOM. Ci si affida quindi solo alle librerie esterne.
NPM prende in prestito dal mondo Linux il concetto di avere un unico repository centralizzato dove scaricare tutte le librerie necessarie per il progetto, repository che si trova su npmjs.com, che contiene librerie di ogni tipo per estendere le funzionalità delle applicazioni per NodeJS.
Npm è utilizzabile anche nel browser per gli stessi scopi, ed anche in quel caso le dipendenze sono gestite tramite package.json
.
Resta da capire come gestire l’importazione di librerie esterne in uno script Node. La prima soluzione individuata da Node fin dalla sua creazione nel 2012 è quella di usare uno standard di importazione che si chiama CommonJs. Lo vediamo in questo esempio:
CommonJS
Export:
const log = (data) => {
console.log(data);
}
module.exports = log;
Import:
const log = require('log.js');
log('ciao');
Con questo sistema è possibile creare più files e importare le dipendenze. In generale CommonJs prevede che da ogni file venga esportato un solo oggetto (di qualunque tipo). Il sistema funziona allo stesso modo anche con le librerie di terze parti.
Dal 2015, tuttavia con ES6 viene introdotto il nuovo standard ES Module, utilizzabile anche nel browser, che ha una sintassi diversa e permette di importare, a partire dallo stesso sorgente, più di un oggetto. Bisogna quindi dichiarare cosa si esporta e cosa si importa:
ES Modules
Import
const log = (data) => {
console.log(data);
}
export log;
Export:
import {log} from 'log.js';
log('ciao');
Inoltre nel package.json
bisogna aggiungere la voce:
"type": "module"
ES Modules è sicuramente un sistema più moderno. Tuttavia ad oggi (2025) nella maggior parte delle librerie si usa ancora CommonJS in NodeJs mentre ESM è l’unico sistema usato nel browser (dove CommonJS non è disponibile).
E’ anche possibile usare entrambi abilitando prima ESM come visto sopra e poi eseguendo le seguenti istruzioni ad inizio script per abilitare anche CommonJS:
import { createRequire } from "module";
const require = createRequire(import.meta.url);
Esempi e prime applicazioni di base
Input terminale
NodeJs è prima di tutto una applicazione da terminale e quindi è possibile interagire con l’utente.
Qui un esempio di lettura input utente usando la libreria Readline.
const readline = require('readline');
const { stdin: input, stdout: output } = require('process');
const rl = readline.createInterface({ input, output });
rl.question('Who are you?', name => {
console.log(`Hey there ${name}!`);
rl.close();
});
L’oggetto process da un insieme di informazioni relative al processo in esecuzione:
- stdin e stdout: gli stream di input ed output (come in C++);
- argv: gli argomenti;
- env: visualizzare le variabili di ambiente
Client web
Una chiamata ad un server remoto può essere fatta usando la libreria “node-fetch”, che ha un comportamento identico a fetch su browser.
E’ possibile installare node-fetch con npm. Qui un esempio di codice:
import fetch from 'node-fetch';
fetch('https://dummy.restapiexample.com/api/v1/employees')
.then(response => response.json())
.then(data => console.log(data));
Lettura e scrittura file.
Qui un semplice esempio di lettura file con la libreria fs.
const fs = require('fs');
fs.readFile("miofile.txt", (error, data) => {
if (error) {
throw error;
}
console.log(data.toString());
});
Qui invece un esempio di scrittura:
const fs= require('fs');
fs.writeFile("miofile.txt", "my text", (error) => {
if (error) {
throw error;
}
console.log("Data written");
});
Files e directory
Qui un elenco di funzioni sui files:
Comando | Azione | opzioni |
readdir | legge il contenuto di un folder | name callback |
mkdir | crea folder | name, callback |
rmdir | cancella folder | name, callback |
unlink | cancella un file | name, callback |
copyFile | copia un file | origin, dest, callback |
Ad esempio per leggere un folder:
const fs = require("fs");
fs.readdir("dir", (error, files) => {
if (error) {
throw error;
}
console.dir(files);
});
Server web
Concludiamo questa lezione mostrando come con NodeJs è molto semplice creare un semplice web server. Approfondiremo la parte web in apposita lezione.
let http = require("http");
http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello World!\n');
}).listen(8081);
console.log('Server running at port 8081');
Async await
La notazione async…await è un sistema per rendere più leggibili le promise. Ad esempio questa è una fetch gestita con then-catch.
fetch(url)
.then(r => r.json())
.then(data => console.log(data))
.catch(e => console.error(e));
Per essere gestita tramite async-await bisogna includerla in una funzione async in questo modo:
let load = async () => {
try {
const r = await fetch(url);
const data = await r.json();
console.log(data);
} catch (e) {
console.error(e);
}
}
Le due notazioni sono identiche. Il grosso vantaggio di async await è la leggibilità: “sembra” che il codice asincrono diventi sincrono e quindi che lo script si fermi ad aspettare (await) che la fetch si concluda. In realtà è del tutto illusorio: in realtà c’è sempre una promise e codice asincrono e quindi semplicemente il codice che stiamo vedendo è solo zucchero sintattico: prima di essere eseguito lo script qui sopra viene prima trasformato in quello precedente e poi eseguito.
Va poi osservato che await è utilizzabile solo in funzioni marcate come async, quindi non direttamente nello script principale. Esiste però una soluzione, che sono le funzioni anonime autoeseguenti:
(async () => {
try {
const r = await fetch(url);
const data = await r.json();
console.log(data);
} catch (e) {
console.error(e);
}
})();
Questa funzione viene dichiarata e messa subito in coda di esecuzione ed eseguita appena possibile. Questo codice, così come gli async-await, funziona sia su NodeJS che su browser.
Si ricorda tuttavia di usare questa notazione solo quando si ha raggiunto sufficiente dimestichezza con le promise.