Node.js permet d’exécuter du JavaScript en dehors du navigateur : serveurs web, outils en ligne de commande, scripts d’automatisation. Il associe :
- V8, le moteur JavaScript de Chrome, qui exécute votre code ;
- libuv, une bibliothèque qui gère les entrées-sorties (fichiers, réseau, minuteries) de façon asynchrone ;
- une bibliothèque standard de modules (
node:fs,node:http,node:crypto…).
Votre code s’exécute sur un seul thread. Les opérations lentes (lire un fichier, attendre une requête) sont déléguées au système ; Node continue à traiter d’autres tâches et reprend votre code quand le résultat arrive. C’est la boucle d’événements, que nous détaillerons plus loin. Conséquence importante : un calcul long et synchrone bloque tout le serveur.
Par rapport au navigateur : pas de window, pas de document, pas de DOM. En revanche, globalThis, console, setTimeout, fetch, URL ou structuredClone sont disponibles. On utilise une version LTS (numéro pair) en production : Node 26 est la LTS actuelle.
Exécuter du code
node --version # v26.x (LTS actuelle)
node # REPL : console interactive (.exit pour quitter)
node script.js # exécuter un fichier
node --watch server.js # relancer automatiquement à chaque modification
node --env-file=.env app.js # charger un fichier .env (option stable)
node outil.ts # exécuter du TypeScript : types retirés, non vérifiés
L’objet process
process est un objet global qui représente le programme en cours.
// node saluer.js Ada --majuscules
console.log(process.argv);
// [ '/usr/bin/node', '/home/ada/saluer.js', 'Ada', '--majuscules' ]
console.log(process.platform, process.version, process.cwd());
Les deux premiers éléments de process.argv sont le chemin de Node et celui du script. Pour analyser les options, util.parseArgs (stable depuis Node 20) évite de tout coder à la main :
const { parseArgs } = require("node:util");
const { values, positionals } = parseArgs({
args: process.argv.slice(2),
options: {
port: { type: "string", short: "p", default: "3000" },
verbose: { type: "boolean", short: "v", default: false },
},
allowPositionals: true,
});
// node serve.js -p 8080 -v public => values.port === "8080", positionals = ["public"]
Les variables d’environnement
La configuration (port, URL de base de données, clés d’API) se lit dans process.env. Ce n’est pas dans le code : on peut ainsi utiliser le même programme en développement et en production.
const config = {
port: Number(process.env.PORT ?? 3000), // les valeurs sont TOUJOURS des chaînes
nodeEnv: process.env.NODE_ENV ?? "development",
databaseUrl: process.env.DATABASE_URL,
};
if (!config.databaseUrl) {
console.error("DATABASE_URL manquante");
process.exit(1); // échouer tôt et clairement
}
Validez la configuration au démarrage : il vaut mieux refuser de démarrer qu’échouer au milieu de la nuit sur la première requête.
Les codes de sortie
Un programme qui se termine renvoie un code de sortie : 0 pour un succès, autre chose pour une erreur. Les scripts shell, la CI et Docker s’en servent. Préférez process.exitCode = 1 (le programme termine proprement ses tâches en cours) à process.exit(1) (arrêt immédiat), sauf au démarrage.
À retenir
Node = V8 + libuv + bibliothèque standard, sur un thread non bloquant. process.argv et util.parseArgs pour les arguments, process.env (des chaînes) pour la configuration, et un code de sortie pour communiquer le résultat.
Exercices
Les solutions et les tests restent sur le serveur. Dans l'espace étudiant, ton code est exécuté et corrigé, et le tuteur donne des indices avant la solution.
Analyser les arguments avec util.parseArgs
Écrivez
parseCliArgs(args)(tableau d’arguments, sans les deux premiers éléments deprocess.argv) avecutil.parseArgs:- option
--port/-p(chaîne, défaut"3000"), renvoyée en nombre ; - option
--verbose/-v(booléen, défautfalse) ; - arguments positionnels renvoyés dans
files.
Renvoyez
{ port, verbose, files }.const { parseArgs } = require("node:util"); function parseCliArgs(args) { // À compléter }- option
Charger une configuration validée
Écrivez
loadConfig(env)(un objet commeprocess.env) qui renvoie un objet gelé (Object.freeze) :port:env.PORTconverti en entier, 3000 par défaut ; lance uneErrorsi ce n’est pas un entier entre 1 et 65535 ;nodeEnv:env.NODE_ENVou"development";databaseUrl:env.DATABASE_URL, obligatoire (sinonErrordont le message contientDATABASE_URL).
function loadConfig(env) { // À compléter }Comprendre le modèle de Node
Une route de votre serveur Node calcule pendant 5 secondes une boucle synchrone. Que se passe-t-il pour les autres utilisateurs ?
- Rien, chaque requête a son propre thread
- Leurs requêtes attendent : la boucle d'événements est bloquée
- Node crée automatiquement un nouveau processus
Quiz de fin de leçon
Que contient
process.argv[2]pournode app.js --port 80?- node
- app.js
- --port
De quel type sont les valeurs de
process.env?- Du type d'origine (nombre, booléen)
- Toujours des chaînes (ou undefined)
- Des objets JSON
Quel code de sortie signale un succès ?
- 0
- 1
- 200
La suite du cours
- Modules CommonJS, ES modules et npm18 min
- Asynchrone : callbacks, promesses et boucle d'événements20 min
- Fichiers et chemins : node:fs et node:path18 min
- Événements, streams et serveur HTTP natif20 min