process.env est un objet avec une propriété par variable d'environnement que le shell a passée à votre programme Node.js : process.env.PORT, process.env.DATABASE_URL, etc. Une variable non définie vaut undefined, et une variable définie est toujours une chaîne. Lisez-la une fois au démarrage, donnez-lui une valeur par défaut et convertissez-la dans le type voulu.
Le programme a affiché shop on port 8080 in eu-west (REGION n'a jamais été définie, donc sa valeur par défaut a pris le relais), puis string number : la variable reste du texte tant que Number() ne l'a pas convertie. Supprimez les deux premières assignations et relancez pour voir toutes les valeurs par défaut.
Définir des variables d'environnement dans le shell
Les variables viennent de l'endroit où Node.js est lancé. Dans un terminal :
// 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
Les plateformes d'hébergement (Heroku, Render, Vercel, Docker, Kubernetes) ont une page de réglages ou un fichier pour la même chose ; votre code les lit de la même façon.
Tout est une chaîne
C'est de là que viennent la plupart des bugs avec process.env. 'false' et '0' sont des chaînes non vides, donc truthy :
La vérification naïve a affiché debug is ON pour une variable valant false, donc comparez avec la chaîne exacte attendue. Pour les nombres, Number(process.env.X) transforme une valeur absente en NaN, donc appliquez la valeur par défaut avant la conversion, comme le premier exemple le fait avec ??.
NODE_ENV
NODE_ENV est une convention, pas une fonctionnalité de Node.js : Node.js ne la définit jamais. Ce sont les bibliothèques qui la lisent. Express, par exemple, masque les stack traces des pages d'erreur quand elle vaut production, et beaucoup d'outils sautent les vérifications réservées au développement.
Le programme a affiché mode: production et verbose logs: false ; remplacez 'production' par 'development' et la seconde ligne s'inverse. Tenez-vous-en à production, development et test, car les bibliothèques vérifient ces mots exacts.
Fichiers .env : --env-file et dotenv
Taper chaque variable avant node devient vite pénible. Un fichier .env les garde dans le dossier du projet, une par ligne :
// .env
PORT=8080
DATABASE_URL=postgres://localhost/shop
API_KEY=dev-key-123
Node.js 20.6 et suivants le lisent avec un flag, sans package :
node --env-file=.env app.js
Sur les versions plus anciennes, ou si vous préférez, installez le package dotenv (npm install dotenv) et chargez-le tout en haut de votre fichier d'entrée, avant tout code qui lit process.env :
require('dotenv').config(); // copies .env into process.env
console.log(process.env.PORT); // 8080
Aucun des deux n'écrase une variable déjà définie dans le shell, donc les réglages de production l'emportent sur le fichier.
Échouer tôt si une variable manque
Une URL de base de données manquante doit arrêter le programme au démarrage avec un message clair, pas le faire planter à la première requête une heure plus tard :
Le programme a affiché Missing environment variables: API_KEY ; ajoutez process.env.API_KEY = 'test'; en haut et il affiche Config OK. Dans un vrai programme, faites suivre le message d'un process.exit(1), car un code de sortie non nul est ce qui permet à un script de déploiement ou à une plateforme de conteneurs de voir que le démarrage a échoué.
Ne commitez jamais de secrets
Ajoutez .env au .gitignore le jour où vous le créez. Commitez plutôt un .env.example avec les noms des variables et de fausses valeurs, pour que les autres sachent quoi définir. Une clé qui a été poussée un jour dans un dépôt doit être considérée comme compromise et remplacée, même si vous supprimez le commit ensuite.
Questions fréquentes
Pourquoi process.env.MY_VAR vaut-il undefined ?
La variable n'a pas été définie dans le shell qui a lancé Node.js, ou elle l'a été dans un autre terminal. Un fichier .env n'est pas lu automatiquement non plus : lancez Node.js avec --env-file=.env ou chargez-le avec dotenv avant de lire la valeur.
Peut-on modifier process.env pendant l'exécution ?
Oui. Assigner process.env.X = 'value' la change pour le processus courant et pour tous les processus enfants qu'il lance ensuite, mais jamais pour le shell qui a lancé Node.js. Node.js convertit la valeur assignée en chaîne.
Les noms de variables d'environnement sont-ils sensibles à la casse ?
Sous Linux et macOS, oui : PORT et port sont deux variables. Sous Windows, non. Tenez-vous-en à des noms en majuscules avec des underscores et la question ne se pose jamais.
Le navigateur peut-il lire process.env ?
Non. Les navigateurs n'ont pas de variables d'environnement. Des outils de build comme Vite et Next.js copient certaines variables dans votre code frontend au moment du build, ce qui veut aussi dire que ces valeurs sont publiques.