Menu

process.env in Node.js: leggere le variabili d'ambiente

process.env è un oggetto con le variabili d'ambiente con cui è stato avviato il tuo programma Node.js. Ogni valore è una stringa o undefined, quindi converti tu numeri e booleani e dai a ogni variabile un default.

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

process.env è un oggetto con una proprietà per ogni variabile d'ambiente che la shell ha passato al tuo programma Node.js: process.env.PORT, process.env.DATABASE_URL e così via. Una variabile non impostata vale undefined, e una variabile impostata è sempre una stringa. Leggila una volta all'avvio, dalle un default e convertila nel tipo che ti serve.

Ha stampato shop on port 8080 in eu-west (REGION non è mai stata impostata, quindi è subentrato il suo default), poi string number: la variabile è testo finché Number() non la converte. Cancella le prime due assegnazioni ed eseguilo di nuovo per vedere tutti i default.

Impostare le variabili d'ambiente nella shell

Le variabili arrivano da dove viene avviato Node.js. In un terminale:

// macOS and Linux: for one command
PORT=8080 NODE_ENV=production node app.js

// macOS and Linux: for the rest of the terminal session
export PORT=8080

// Windows PowerShell
$env:PORT = "8080"; node app.js

// Windows cmd.exe
set PORT=8080
node app.js

Le piattaforme di hosting (Heroku, Render, Vercel, Docker, Kubernetes) hanno una pagina di impostazioni o un file per la stessa cosa; il tuo codice le legge nello stesso modo.

Tutto è una stringa

Da qui nasce la maggior parte dei bug con process.env. 'false' e '0' sono stringhe non vuote, quindi sono truthy:

Il controllo ingenuo ha stampato debug is ON per una variabile impostata a false, quindi confronta con la stringa esatta che ti aspetti. Per i numeri, Number(process.env.X) trasforma un valore mancante in NaN, quindi applica il default prima di convertire, come fa il primo esempio con ??.

NODE_ENV

NODE_ENV è una convenzione, non una funzionalità di Node.js: Node.js non la imposta mai. La leggono le librerie. Express, per esempio, nasconde gli stack trace dalle pagine di errore quando vale production, e molti strumenti saltano i controlli pensati solo per lo sviluppo.

Ha stampato mode: production e verbose logs: false; cambia 'production' in 'development' e la seconda riga si inverte. Usa solo production, development e test, perché le librerie controllano proprio quelle parole.

File .env: --env-file e dotenv

Scrivere ogni variabile prima di node diventa presto noioso. Un file .env le tiene nella cartella del progetto, una per riga:

// .env
PORT=8080
DATABASE_URL=postgres://localhost/shop
API_KEY=dev-key-123

Node.js 20.6 e successivi lo leggono con un flag, senza pacchetti:

node --env-file=.env app.js

Sulle versioni più vecchie, o se preferisci, installa il pacchetto dotenv (npm install dotenv) e caricalo in cima al file di ingresso, prima di qualsiasi codice che legga process.env:

require('dotenv').config(); // copies .env into process.env

console.log(process.env.PORT); // 8080

Nessuno dei due sovrascrive una variabile già impostata nella shell, quindi le impostazioni di produzione hanno la precedenza sul file.

Fallire subito se manca una variabile

Un URL del database mancante deve fermare il programma all'avvio con un messaggio chiaro, non farlo crashare alla prima richiesta un'ora dopo:

Ha stampato Missing environment variables: API_KEY; aggiungi process.env.API_KEY = 'test'; in cima e stampa Config OK. In un programma vero, fai seguire il messaggio da process.exit(1), perché un exit code diverso da zero è il modo in cui uno script di deploy o una piattaforma di container capisce che l'avvio è fallito.

Mai fare commit dei segreti

Metti .env nel .gitignore il giorno in cui lo crei. Fai invece il commit di un .env.example con i nomi delle variabili e valori finti, così gli altri sanno cosa impostare. Una chiave finita anche una sola volta in un repository va considerata compromessa e sostituita, anche se poi cancelli il commit.

Domande frequenti

Perché process.env.MY_VAR è undefined?

La variabile non è stata impostata nella shell che ha avviato Node.js, oppure è stata impostata in un altro terminale. Nemmeno un file .env viene letto in automatico: avvia Node.js con --env-file=.env o caricalo con dotenv prima di leggere il valore.

Posso modificare process.env mentre il programma gira?

Sì. Assegnare process.env.X = 'value' la cambia per il processo corrente e per ogni processo figlio avviato dopo, ma mai per la shell che ha lanciato Node.js. Node.js converte in stringa il valore che assegni.

I nomi delle variabili d'ambiente sono case sensitive?

Su Linux e macOS sì: PORT e port sono due variabili diverse. Su Windows no. Usa nomi in maiuscolo con gli underscore e il problema non si pone mai.

Il browser può leggere process.env?

No. I browser non hanno variabili d'ambiente. Strumenti di build come Vite e Next.js copiano alcune variabili nel codice frontend al momento della build, il che significa anche che quei valori sono pubblici.

Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

Inizia