Node.js — les bases utiles
1) Node.js, c’est quoi exactement ?
- Node.js = un environnement d’exécution pour JavaScript hors navigateur.
- Il embarque V8 (moteur JS de Chrome) et libuv (boucles d’événements, IO non bloquants).
- Idéal pour des apps réseau concurrentes : APIs, SSR, microservices, CLIs, workers, bots…
2) package.json — le plan de ton projet
npm init -y
# ou pnpm init -y / yarn init -y"type": "module"active les ES Modules (importsimport ... from ...).scripts.dev:--watchrecharge automatiquement le processus.enginesdocumente la version Node minimale.
3) Importer des modules : CommonJS vs ESM
Deux styles possibles :
// package.json SANS "type":"module"
const http = require('node:http');
// ...
module.exports = { /* ... */ }Pourquoi 'node:http' ?
Préfixer les modules cœur par node: (ex. node:http, node:fs) indique
clairement à Node qu’il s’agit d’un module interne. Avantages : résolution plus fiable, messages d’erreur plus précis.
4) Écrire un petit serveur HTTP
- Serveur minimal
import http from 'node:http'; const PORT = 8000; const server = http.createServer((req, res) => { res.end('Hello from the server!'); }); server.listen(PORT, () => { console.log(`server running on port: ${PORT}`); });createServer(cb)fournit req (requête) et res (réponse) — le cœur du request/response cycle. - Écrire vs terminer une réponse
import http from 'node:http'; const server = http.createServer((req, res) => { // On peut envoyer plusieurs morceaux : res.write('This is some data\n'); res.write('This is some more data\n'); // Toujours terminer la réponse : res.end('This is from the server', 'utf8', () => { console.log('response end'); }); }); server.listen(8000); - Content-Type, status & chemins
import http from 'node:http'; import { URL } from 'node:url'; const server = http.createServer(async (req, res) => { const url = new URL(req.url ?? '/', 'http://localhost'); const { pathname } = url; if (req.method === 'GET' && pathname === '/health') { res.writeHead(200, { 'content-type': 'application/json; charset=utf-8' }); return res.end(JSON.stringify({ ok: true, ts: Date.now() })); } if (req.method === 'POST' && pathname === '/echo') { const chunks = []; for await (const chunk of req) chunks.push(chunk); const body = Buffer.concat(chunks).toString('utf8'); res.writeHead(201, { 'content-type': 'application/json; charset=utf-8' }); return res.end(JSON.stringify({ youSent: body })); } res.writeHead(404, { 'content-type': 'text/plain; charset=utf-8' }); res.end('Not Found'); }); server.listen(8000);
5) Streaming & fichiers (bonus utile)
Lire et renvoyer un gros fichier sans le charger en mémoire :
import http from 'node:http';
import fs from 'node:fs';
http.createServer((req, res) => {
if (req.url === '/bigfile') {
res.writeHead(200, { 'content-type': 'application/octet-stream' });
const stream = fs.createReadStream('./big.bin');
stream.pipe(res); // streaming backpressure-friendly
} else {
res.end('ok');
}
}).listen(8000);6) Arrêt propre (graceful shutdown)
import http from 'node:http';
const server = http.createServer((req, res) => res.end('bye'));
server.listen(8000, () => console.log('up'));
process.on('SIGINT', () => stop('SIGINT'));
process.on('SIGTERM', () => stop('SIGTERM'));
function stop(signal) {
console.log('closing on', signal);
server.close(err => {
if (err) {
console.error('close error', err);
process.exitCode = 1;
}
process.exit();
});
}7) Quand passer à un framework ?
- Express : ultra-répandu, écosystème massif, middleware simple.
- Fastify : très rapide, schémas JSON, DX moderne.
- NestJS : structure d’app complète (DI, modules, decorators).
Récap express
- Node exécute JS côté serveur via V8 et une Event Loop non bloquante.
package.json: scripts,"type":"module", versions.- Modules : CommonJS (
require) ou ESM (import). Préfixenode:pour les modules cœur. - HTTP :
createServer,writeHead,write,end, parsing de l’URL, streaming. - Qualité : types de contenu corrects, gestion d’erreurs, shutdown propre.