Runtime Node.js et système de modules
L'event loop, l'objet process, et le système de modules CommonJS/ESM typés avec TypeScript.
Prérequis TypeScript : ce chapitre suppose que vous avez suivi la séance 3 (TypeScript). Les exemples utilisent des types, des interfaces et des imports ESM.
🧠 Qu'est-ce que Node.js
Node.js n'est pas un framework. C'est un runtime JavaScript — un environnement qui exécute du JavaScript (ou du TypeScript transpilé) en dehors du navigateur, avec accès aux API système : fichiers, réseau, processus, mémoire.
// Node.js expose des API système absentes du navigateur
import { stdout } from "node:process"
stdout.write("Bonjour depuis Node.js\n")Le moteur V8 de Chrome est au cœur de Node.js. Node.js y a ajouté les API système pour en faire un runtime serveur.
Runtime ≠ Framework
- Un runtime exécute le code (Node.js, Deno, Bun).
- Un framework structure l'application (Express, Nest, Fastify).
- Node.js est le runtime — Express est un framework qui s'exécute dessus.
🔄 L'event loop — architecture non-bloquante
Node.js est single-threaded mais non-bloquant. Une seule thread exécute le code JavaScript, mais les I/O (fichier, réseau, base de données) sont déléguées à des mécanismes asynchrones.
import { readFile } from "node:fs/promises"
// Cette ligne ne bloque PAS le thread
const data = await readFile("fichier.txt", "utf8")
console.log(data) // exécuté quand le fichier est lu, plus tardL'event loop tourne en boucle en 6 phases :
| Phase | Ce qui s'y passe |
|---|---|
| timers | setTimeout, setInterval (appels à échéance) |
| pending callbacks | Callbacks I/O système en attente |
| idle, prepare | Interne |
| poll | Récupération des I/O prêts à traiter |
| check | setImmediate() |
| close callbacks | socket.on('close') |
import { setTimeout, setImmediate } from "node:timers"
setTimeout(() => {
console.log("setTimeout — phase timers")
}, 0)
setImmediate(() => {
console.log("setImmediate — phase check")
})
// L'ordre d'exécution dépend du contexte (main script vs callback I/O)Une idée reçue
Node.js n'est pas "plus rapide" que les autres runtimes. Il excelle sur les charges I/O-bound (beaucoup de connexions, peu de calcul CPU). Pour du CPU intensif, il faut du clustering ou déporter la charge.
📦 L'objet process
process est un objet global qui donne accès à l'environnement d'exécution.
import { env, argv, cwd } from "node:process"
// Variables d'environnement (string | undefined)
const port = Number(env.PORT ?? 3000)
const nodeEnv = env.NODE_ENV ?? "development"
// Arguments CLI — argv[0] = "node", argv[1] = chemin du script
const args = argv.slice(2) // ["--port", "8080"]
// Dossier courant d'exécution
const currentDir = cwd()TypeScript (avec @types/node) donne un type précis à process :
// Sans @types/node, process est any
// Avec @types/node, chaque propriété est typée
interface ProcessEnv {
PORT?: string
NODE_ENV?: "development" | "production"
}
declare global {
namespace NodeJS {
interface Process {
env: ProcessEnv
}
}
}📜 Le système de modules — CommonJS vs ESM
Node.js organise le code en modules. Deux systèmes coexistent.
CommonJS (historique)
C'est le système par défaut des fichiers .js dans Node.js. Chaque fichier est un module isolé — il n'y a pas de mot-clé import / export : on utilise module.exports pour exposer et require() pour importer.
// math.js — export CommonJS
const PI = 3.14159
function circonférence(rayon) {
return 2 * PI * rayon
}
module.exports = { circonférence }// index.js — import CommonJS
const { circonférence } = require("./math")
console.log(circonférence(10)) // 62.8318Caractéristiques de CommonJS :
module.exportspour exporter,require()pour importer- Import synchrone (bloquant) — les dépendances sont chargées avant l'exécution
- Supporté nativement, aucune configuration requise
- Limitation : pas de chargement conditionnel, pas de tree-shaking, pas de notation
import { x }
ES Modules (standard moderne)
Les ES Modules (ESM) sont le standard JavaScript. Dans Node.js, ils s'activent avec :
- Extension
.mjs, ou "type": "module"danspackage.json
// math.mjs — export ESM
export const PI = 3.14159
export function circonférence(rayon) {
return 2 * PI * rayon
}// index.mjs — import ESM
import { circonférence, PI } from "./math.mjs"
console.log(circonférence(10))Règle d'import ESM
Dans les fichiers .ts avec moduleResolution: "NodeNext", l'extension .js est obligatoire dans les chemins d'import, même pour des fichiers .ts ou .mts. Le loader TypeScript résout le fichier source.
// ❌ Incorrect — extension manquante
import { circonférence } from "./math"
// ✅ Correct
import { circonférence } from "./math.js"📋 Récapitulatif
| Aspect | CommonJS | ES Modules |
|---|---|---|
| Extension | .js (ou .cjs) | .mjs / .js avec "type": "module" |
| Export | module.exports / export | export |
| Import | require() | import |
| Ordre | Synchrone, bloquant | Asynchrone (dans le navigateur), statique |
| TypeScript | module: "CommonJS" | module: "NodeNext" |
Quiz du chapitre
Node.js
Terminez le quiz du chapitre pour le marquer comme complété.
Installation et configuration de Node.js
L'installation de Node.js inclut automatiquement l'installation de NPM (Node Package Manager). Voici les étapes pour installer Node.js sur différents systèmes d'exploitation.
Système de fichiers et flux en Node.js
Module fs pour lire et écrire des fichiers, et streams pour traiter efficacement de grandes quantités de données de manière asynchrone.