Menu

Runtime Node.js: come JavaScript gira fuori dal browser

Cos'è il runtime Node.js, in cosa differisce dal browser e quali API fondamentali (globali, moduli, process, fs) rendono possibile JavaScript lato server.

Questa pagina include editor eseguibili: modifica, esegui e vedi subito l'output.

Cos'è davvero Node

Node.js è un programma che installi sul tuo computer e che esegue file JavaScript. È la descrizione più semplice, ed è accurata. Quando scrivi node script.js, Node legge il file, lo passa al motore V8 di Google (il motore JavaScript di Chrome) e lo esegue, con una grande libreria di API aggiuntive per le cose che V8 non sa fare da solo.

V8 sa eseguire JavaScript. Non sa aprire un file, restare in ascolto su un socket TCP, avviare un processo o leggere una variabile d'ambiente. Node fornisce tutto questo, scritto in C++, e lo espone al tuo JavaScript sotto forma di moduli integrati.

node --version
node script.js

Quindi Node non è un linguaggio. Non è un framework. È un runtime: V8 più una libreria standard, più un sistema di moduli, più un event loop. Tutto qui.

Un primo script

Qualsiasi file .js è un programma Node valido. Niente codice di contorno, niente funzione main:

console.log funziona come nel browser. Template literal, Date, array, promise: tutte le funzionalità del linguaggio che già conosci vengono da V8 e si comportano allo stesso modo. Ciò che cambia in Node è quello che c'è a disposizione intorno al linguaggio.

Globali che esistono solo in Node

Il browser ha window, document, localStorage, fetch. Node ha un insieme diverso di globali, pensato per un runtime lato server:

  • process è il processo Node in esecuzione. Contiene le variabili d'ambiente (process.env), gli argomenti da riga di comando (process.argv) e i metodi per terminare (process.exit(1)).
  • __filename e __dirname ti danno il percorso assoluto del file corrente e della sua cartella. (Nei moduli ES non esistono: al loro posto usi import.meta.url.)
  • global è l'oggetto di primo livello, l'equivalente Node di window.

Non c'è document e non c'è window. Se provi a usarli, ottieni un ReferenceError. Di solito è il primo indizio che una libreria è stata scritta per il browser e non girerà in Node così com'è.

Argomenti da riga di comando e ambiente

Una grossa fetta di ciò per cui si usa Node (CLI, script di build, server) ha bisogno di leggere argomenti e variabili d'ambiente. Entrambi vivono su process:

process.argv è un array: le prime due voci sono il percorso dell'eseguibile Node e quello dello script, quindi gli argomenti veri partono dall'indice 2. process.env è un oggetto semplice con le variabili d'ambiente: leggere da lì NODE_ENV, PORT o le chiavi API è una pratica standard.

Moduli integrati

Node include una libreria standard accessibile tramite require (CommonJS) o import (ESM). I nomi dei moduli iniziano con node: per rendere esplicito che sono integrati:

Quelli che userai di più:

  • node:fs: leggere e scrivere file. Usa node:fs/promises per la versione con async/await.
  • node:path: unire, risolvere e analizzare percorsi di file in modo multipiattaforma.
  • node:http / node:https: costruire server HTTP e fare richieste.
  • node:url: analizzare e costruire URL.
  • node:os: informazioni sulla macchina che ospita il programma.
  • node:crypto: hashing, byte casuali, crittografia.

Questi non li installi. Arrivano con Node. Tutto il resto arriva da npm.

L'event loop, in breve

Node esegue il tuo JavaScript su un solo thread, ma gestisce molte cose contemporaneamente. Il trucco è l'event loop. Quando chiami qualcosa di asincrono (la lettura di un file, una richiesta HTTP, un timer), Node passa il lavoro vero al sistema operativo (o al suo pool di thread) e continua a eseguire. Quando il lavoro finisce, una callback viene messa in coda e il loop la raccoglie quando il codice corrente ha terminato.

L'ordine di stampa è 1, 4, 2, 3. Prima gira il codice sincrono. Poi i microtask (le promise risolte). Poi i timer. Ecco perché un ciclo lento e pesante per la CPU blocca tutto il server: c'è un solo thread per il tuo codice. La concorrenza di Node riguarda l'I/O, non il calcolo.

Un piccolo server HTTP

Il vantaggio di tutto questo è che un server web funzionante sta in poche righe:

Nessun framework, nessuna dipendenza. createServer riceve una funzione che viene eseguita a ogni richiesta; listen fa sì che l'event loop inizi a elaborare le connessioni in arrivo. Le app reali usano Express o Fastify sopra questo, ma sotto c'è lo stesso modulo integrato http.

Node contro il browser

Vale la pena essere espliciti su cosa si porta dietro e cosa no:

Funziona in entrambiSolo NodeSolo browser
Funzionalità del linguaggio (classi, promise, async/await)fs, http, process, __dirnamewindow, document, DOM
console.logrequire di CommonJS / particolarità ESM di NodelocalStorage, sessionStorage
fetch (Node 18+)Accesso al file system e ai socket di reteEventi utente, rendering
setTimeout, setIntervalProcessi figli, streamHistory API, navigator

Il Node moderno ha adottato diverse API del browser (fetch, URL, AbortController, structuredClone), quindi la distanza è minore di un tempo. Ma il DOM non arriverà in Node, e il file system non arriverà nel browser.

Node, Deno e Bun

Node è la scelta di default, ma non è più l'unico runtime JavaScript. Deno e Bun sono alternative: Deno arriva dal creatore originale di Node, Bun da un team più recente concentrato sulla velocità. Eseguono JavaScript (e TypeScript, nativamente), includono strumenti integrati come test runner e bundler, e differiscono da Node nel modo in cui gestiscono moduli, permessi e installazione dei pacchetti.

Per imparare JavaScript, Node resta il posto dove stanno documentazione, tutorial e offerte di lavoro. I concetti (event loop, moduli, API integrate) si trasferiscono quasi interamente agli altri runtime. Impara prima Node; passa agli altri quando un progetto lo richiede.

Eseguire script, in fretta

Alcuni modi per eseguire davvero il codice mentre lavori:

# Run a file
node script.js

# Run a one-liner
node -e "console.log(2 ** 10)"

# Open the REPL (interactive prompt)
node

# Watch a file and re-run on save (Node 18.11+)
node --watch script.js

Il REPL è un comodo blocco per appunti quando vuoi verificare cosa restituisce un metodo senza creare un file. --watch è utile durante lo sviluppo: salvi e Node riesegue automaticamente lo script.

Prossimo passo: gestire gli errori

Eseguire il codice è una cosa; gestirlo quando qualcosa va storto è un'altra. Le letture di file falliscono, le richieste HTTP vanno in timeout, il parsing del JSON lancia errori. Il prossimo capitolo parla di try/catch, dei tipi di errore e degli schemi per affrontare ciò che si rompe, cosa che in un programma Node, prima o poi, succede a tutto.

Domande frequenti

Cos'è il runtime Node.js?

Node.js è un programma che esegue JavaScript fuori dal browser. Unisce il motore V8 di Google (lo stesso che esegue JS in Chrome) a uno strato in C++ che fornisce le API che V8 da solo non ha: accesso al file system, rete, processi, timer. È questa combinazione che ti permette di costruire server, CLI e strumenti di build in JavaScript.

In cosa è diverso Node dal browser?

Entrambi eseguono JavaScript, ma le API intorno al linguaggio sono diverse. Il browser ti dà window, document e il DOM. Node ti dà process, fs, http, __dirname e il caricamento dei moduli CommonJS/ESM. In Node non c'è il DOM e nel browser non c'è il file system: il linguaggio è condiviso, la piattaforma no.

Node.js è un framework o un runtime?

Un runtime. Node di per sé non impone alcuna struttura all'applicazione: esegue JavaScript ed espone delle API. Framework come Express, Next.js o NestJS sono costruiti sopra Node. Deno e Bun sono runtime JavaScript alternativi che fanno concorrenza a Node ma hanno lo stesso ruolo.

Cos'è l'event loop in Node?

L'event loop è ciò che permette a Node di gestire molte cose contemporaneamente su un solo thread. Quando chiami qualcosa di asincrono (la lettura di un file, una richiesta HTTP, un setTimeout), Node passa il lavoro al sistema e continua a eseguire. Quando il lavoro finisce, la sua callback viene messa in coda e l'event loop la raccoglie. Ecco perché fs.readFile non blocca il resto del programma.

Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

INIZIA