Cours Node.js Complet 🟢

Les 12 chapitres essentiels — serveur HTTP, Express, API REST, bases de données et déploiement

12
Chapitres
100+
Exemples de code
Node 22+
Version
A1→C2
Niveaux

CHAPITRE 01

Introduction et installation

🟢 Qu'est-ce que Node.js ?
// hello.js
console.log('Bonjour depuis Node.js !')

// Exécuter
// node hello.js

// Variables d'environnement
console.log(process.env.NODE_ENV) // « development »
console.log(process.argv) // Arguments CLI
console.log(process.cwd()) // Répertoire courant
console.log(__dirname) // Dossier du fichier
console.log(__filename) // Chemin du fichier

Node.js = JavaScript côté serveur. Il exécute le moteur V8 de Chrome hors du navigateur. Créé par Ryan Dahl en 2009, Node.js est utilisé par Netflix, PayPal, LinkedIn, Uber et NASA. Son modèle non-bloquant (event loop) le rend ultra-performant pour les I/O.

⚙️ Installer et démarrer
# Installer (recommandé : nvm)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
nvm install –lts
nvm use –lts

# Vérifier
node –version # v22.x
npm –version # 10.x

# Initialiser un projet
mkdir mon-api && cd mon-api
npm init -y # Crée package.json

# REPL interactif
node # Tapez du JS directement

🏗️ Node.js en résumé
CaractéristiqueNode.js
MoteurV8 (Google Chrome)
ModèleSingle-threaded, event loop, non-bloquant
Package managernpm (défaut), pnpm, yarn
ModulesESM (import) recommandé, CommonJS (require)
UsageAPI REST, microservices, temps réel, SSR, CLI, scripts
ForceI/O intensif (réseau, fichiers, DB)
FaiblesseCPU intensif (calculs lourds) — utiliser Worker Threads
🧠 Quiz
Pourquoi Node.js est « non-bloquant » ?
Node.js utilise un event loop single-threaded. Quand une opération I/O (fichier, réseau, DB) est lancée, Node ne bloque pas — il passe à la tâche suivante et sera notifié quand l'I/O est terminée. Résultat : un seul thread peut gérer des milliers de connexions simultanées.

CHAPITRE 02

Modules et npm

📦 ES Modules (recommandé)
// package.json : ajouter « type »: « module » pour utiliser import/export

// math.js — exporter
export function add(a, b)
export function multiply(a, b)
export default function square(x)

// app.js — importer
import square, from './math.js'
add(2, 3) // 5
square(4) // 16

// Modules Node intégrés
import fs from 'node:fs/promises'
import path from 'node:path'
import from 'node:http'

📋 npm — le gestionnaire de paquets
# Installer un paquet
npm install express # Dépendance de production
npm install -D nodemon # Dépendance de développement

# Raccourcis
npm i express # i = install
npm i -D vitest # -D = –save-dev

# Scripts (package.json)

# Exécuter un script
npm run dev
npm start # Raccourci (pas de « run » pour start/test)
npm test

Node 22+ a –watch intégré : plus besoin de nodemon pour le hot reload. node –watch src/index.js relance automatiquement à chaque changement de fichier.

CHAPITRE 03

Système de fichiers (fs)

📄 Lire et écrire des fichiers
import fs from 'node:fs/promises'
import path from 'node:path'

// Lire un fichier
const content = await fs.readFile('data.txt', 'utf-8')

// Écrire un fichier
await fs.writeFile('output.txt', 'Contenu')

// Ajouter à un fichier
await fs.appendFile('log.txt', 'Nouvelle ligne\n')

// Lire un dossier
const files = await fs.readdir('./src')

// Vérifier l'existence
try catch

// Supprimer
await fs.unlink('old.txt')
await fs.rm('dossier', )

// JSON
const data = JSON.parse(await fs.readFile('data.json', 'utf-8'))
await fs.writeFile('data.json', JSON.stringify(data, null, 2))

// path — manipulation de chemins (cross-platform)
path.join('src', 'utils', 'file.js') // src/utils/file.js
path.resolve('./data') // Chemin absolu
path.extname('image.png') // .png
path.basename('/a/b/file.js') // file.js

Toujours utiliser fs/promises (async) et jamais fs.readFileSync (bloquant) dans un serveur. La version sync bloque l'event loop et empêche Node de traiter d'autres requêtes.

CHAPITRE 04

Async/Await et Promises

⚡ Async/Await
// async/await — syntaxe moderne pour l'asynchrone
async function fetchUser(id)

// Gestion d'erreurs
try catch (err)

// Parallèle — Promise.all (toutes en même temps)
const [users, posts, comments] = await Promise.all([
fetchUsers(),
fetchPosts(),
fetchComments(),
])

// Promise.allSettled — ne fail pas si une échoue
const results = await Promise.allSettled([task1, task2, task3])
results.forEach(r => )

CHAPITRE 05

Serveur HTTP et Express

🌐 Serveur HTTP natif
import from 'node:http'

const server = createServer((req, res) => )

server.listen(3000, () => console.log('http://localhost:3000'))

🚀 Express — le framework standard
// npm install express
import express from 'express'

const app = express()

// Middleware — parser le JSON
app.use(express.json())

// Routes
app.get('/', (req, res) => )

app.get('/users/:id', (req, res) => )

app.post('/users', (req, res) => )

// Middleware personnalisé
function logger(req, res, next)
app.use(logger)

// Démarrer
app.listen(3000, () => console.log('http://localhost:3000'))

Express est le framework Node.js le plus populaire (30M+ téléchargements/semaine). Minimaliste et extensible via des middleware. Alternatives modernes : Fastify (plus rapide), Hono (edge/serverless), Elysia (Bun).

CHAPITRE 06

API REST

🔌 CRUD complet
import express from 'express'
const router = express.Router()

let users = [
,
,
]

// GET /users — Liste
router.get('/', (req, res) => )

// GET /users/:id — Détail
router.get('/:id', (req, res) => )

// POST /users — Créer
router.post('/', (req, res) => )

// PUT /users/:id — Remplacer
router.put('/:id', (req, res) => )

// DELETE /users/:id — Supprimer
router.delete('/:id', (req, res) => )

export default router

// app.js — monter le router
import userRouter from './routes/users.js'

app.use('/api/users', userRouter)

CHAPITRE 07

Bases de données

🗄️ Prisma — l'ORM moderne
# Installation
npm install prisma @prisma/client
npx prisma init

// prisma/schema.prisma
generator client

datasource db

model User

model Post

# Migrer la base
npx prisma migrate dev –name init
npx prisma studio # Interface web pour explorer la DB
// Utilisation dans le code
import from '@prisma/client'
const prisma = new PrismaClient()

// CRUD
const users = await prisma.user.findMany()
const user = await prisma.user.findUnique()
const newUser = await prisma.user.create()
await prisma.user.update()
await prisma.user.delete()

// Relations (include)
const userWithPosts = await prisma.user.findUnique()

Prisma est l'ORM le plus populaire pour Node.js/TypeScript. Schéma déclaratif, migrations automatiques, typage auto, Prisma Studio. Alternatives : Drizzle ORM (plus léger, SQL-like), Sequelize (plus ancien), Mongoose (MongoDB).

CHAPITRE 08

Authentification

🔐 JWT (JSON Web Tokens)
// npm install jsonwebtoken bcrypt
import jwt from 'jsonwebtoken'
import bcrypt from 'bcrypt'

const SECRET = process.env.JWT_SECRET

// Register — hasher le mot de passe
app.post('/register', async (req, res) => )

// Login — vérifier et générer le token
app.post('/login', async (req, res) => )

// Middleware d'authentification
function auth(req, res, next)

// Route protégée
app.get('/profile', auth, async (req, res) => )

CHAPITRE 09

Gestion d'erreurs

🛡️ Error handling Express
// Erreur custom
class AppError extends Error

// Route qui lève une erreur
app.get('/users/:id', async (req, res, next) => )

// Error handler global (APRÈS toutes les routes)
app.use((err, req, res, next) => )

✅ Validation avec Zod
// npm install zod
import from 'zod'

const createUserSchema = z.object()

app.post('/users', (req, res) => )

CHAPITRE 10

Tests

🧪 Tests avec Vitest
// npm install -D vitest

// math.test.js
import from 'vitest'
import from './math.js'

describe('Math utils', () => )

// Test API avec supertest
// npm install -D supertest
import request from 'supertest'
import app from './app.js'

it('GET /api/users returns users', async () => )

CHAPITRE 11

Déploiement

🚀 Variables d'environnement et déploiement
# .env (jamais commité dans Git !)
DATABASE_URL=postgresql://user:pass@localhost:5432/mydb
JWT_SECRET=super_secret_key_123
PORT=3000
NODE_ENV=production

// Charger les variables
// Node 22+ : –env-file intégré
// node –env-file=.env src/index.js

// Utilisation
const port = process.env.PORT || 3000
const secret = process.env.JWT_SECRET

PlateformeTypeIdéal pour
RailwayPaaSDéploiement simple (git push), DB intégrée
RenderPaaSFree tier généreux, PostgreSQL
Fly.ioConteneursEdge deployment, Docker
AWS EC2/ECSIaaS/CaaSContrôle total, entreprise
VercelServerlessAPI Routes (Next.js), edge functions
🐳 Docker
# Dockerfile
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci –omit=dev
COPY . .
EXPOSE 3000
CMD [« node », « src/index.js »]

# .dockerignore
node_modules
.env
.git

CHAPITRE 12

Bonnes pratiques

🏗️ Structure de projet
mon-api/
├── src/
│ ├── index.js # Point d'entrée
│ ├── app.js # Config Express (séparé pour les tests)
│ ├── routes/
│ │ ├── users.js
│ │ └── posts.js
│ ├── middleware/
│ │ ├── auth.js
│ │ └── validate.js
│ ├── services/ # Logique métier
│ │ └── userService.js
│ ├── lib/
│ │ └── prisma.js # Instance Prisma singleton
│ └── utils/
│ └── errors.js
├── prisma/
│ └── schema.prisma
├── tests/
├── .env
├── .gitignore
├── package.json
└── Dockerfile
✅ Bonnes pratiques

✅ À FAIRE
• ESM (import) + « type »: « module »
fs/promises (async) partout
• Variables d'env (.env, jamais en dur)
• Validation input (Zod)
• Error handler global
–watch en dev (Node 22+)
• Séparer app.js et index.js (tests)
helmet + cors middleware
• TypeScript pour les gros projets

❌ À ÉVITER
require() (CommonJS) — préférer ESM
readFileSync dans un serveur
• Secrets en dur dans le code
console.log en production (utiliser winston/pino)
• Ignorer les erreurs async
npm install en prod (utiliser npm ci)
• Pas de validation d'input
any partout en TypeScript
• Callback hell (utiliser async/await)

🧠 Quiz
Différence entre npm install et npm ci ?
npm install lit package.json et peut mettre à jour le lock file. npm ci (clean install) lit strictement package-lock.json, supprime node_modules avant l'installation, et échoue si le lock file ne correspond pas. npm ci est plus rapide et reproductible — toujours l'utiliser en CI/CD et production.
Pourquoi séparer app.js et index.js ?
app.js configure Express (routes, middleware) et l'exporte. index.js importe app et lance app.listen(). Cela permet de tester l'app sans démarrer le serveur — supertest importe app.js directement.

Cours Node.js Complet — Express, API REST et déploiement

Référence : nodejs.org | Express | Prisma