Polar Code 🎭

Command Palette

Search for a command to run...

15
Pièce N°15

Module 15 : Tooling - L'Arsenal du Développeur

Le code, c'est une chose. Mais le transporter, le construire, le tester, le déployer...
C'est tout un écosystème d'outils. Des armes. Des machines.
Certains sont lourds, lents, mais puissants. D'autres légers, rapides, mais limités.

Ici, on parle de l'arsenal moderne.
Ce que tu utilises dans l'ombre pour que ton code survive à la lumière.


15.1 NPM - L'Entrepôt des Armes

Qu'est-ce que NPM ?

// Node Package Manager
// Le plus grand registre de paquets au monde (plus d'un million)
// Deux choses en une :
// 1. Un registre en ligne (npmjs.com) où les gens publient leurs paquets
// 2. Un outil en ligne de commande pour gérer les dépendances

// Sans NPM :
// - Télécharger manuellement chaque librairie
// - Gérer les versions à la main
// - Résoudre les conflits de dépendances dans la douleur

// Avec NPM :
// - `npm install lodash` → C'est fait
// - Gestion automatique des versions
// - Scripts pour automatiser les tâches

Les Fichiers Clés

// package.json - Le manifeste de ton projet
{
  "name": "operation-shadow",
  "version": "1.0.0",
  "description": "Une opération dans l'ombre",
  "main": "src/index.js",
  "type": "module", // Important pour les imports ES6
  
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "test": "vitest",
    "lint": "eslint src/",
    "format": "prettier --write src/"
  },
  
  "dependencies": {
    "vue": "^3.4.0",          // Dépendances production
    "lodash": "^4.17.21"      // ^ = mises à jour mineures acceptées
  },
  
  "devDependencies": {
    "vite": "^5.0.0",         // Dépendances développement
    "vitest": "^1.0.0",
    "eslint": "^8.56.0",
    "prettier": "^3.1.0"
  },
  
  "engines": {
    "node": ">=18.0.0"        // Version Node requise
  },
  
  "keywords": ["espionnage", "javascript"],
  "author": "Agent 47",
  "license": "MIT"
}

// package-lock.json - NE PAS TOUCHER MANUELLEMENT
// Verrouille les versions exactes pour la reproductibilité
// Généré automatiquement par npm

// .npmrc - Configuration de NPM
// registry=https://registry.npmjs.org/
// save-exact=true  // Pour des versions exactes, pas de ^

Commandes Essentielles

# Initialiser un projet
npm init                  # Questions/réponses
npm init -y               # Oui à tout

# Installer des dépendances
npm install lodash        # Ajoute aux dependencies
npm install vite --save-dev  # Ajoute aux devDependencies
npm install              # Installe tout depuis package.json

# Désinstaller
npm uninstall lodash

# Mise à jour
npm update               # Met à jour selon ^ et ~
npm outdated             # Montre les paquets obsolètes

# Exécuter des scripts
npm run dev
npm test
npm run build

# Publication (si tu crées une lib)
npm login
npm publish
npm version patch        # Incrémente la version (1.0.0 → 1.0.1)

Les Versions (SemVer)

// Semantic Versioning : MAJEUR.MINEUR.PATCH
// 1.2.3
// MAJEUR (1) : Changements incompatibles
// MINEUR (2) : Nouvelles fonctionnalités rétro-compatibles
// PATCH (3) : Corrections de bugs rétro-compatibles

// Dans package.json :
"dependencies": {
  "lib": "^1.2.3",  // Mises à jour mineures et patch (1.x.x)
  "lib": "~1.2.3",  // Seulement les patches (1.2.x)
  "lib": "1.2.3",   // Version exacte (recommandé pour les apps)
  "lib": "*",       // N'importe quelle version (DANGEREUX)
  "lib": "latest"   // La dernière (TRÈS DANGEREUX)
}

// npm audit : Vérifie les vulnérabilités
npm audit
npm audit fix

NPM vs Yarn vs PNPM

# NPM (officiel, stable, lent avec node_modules)
npm install

# Yarn (Facebook, plus rapide, yarn.lock)
yarn add lodash
yarn install

# PNPM (performant, espace disque, liens durs)
pnpm add lodash
pnpm install

# Ils font tous la même chose, choix souvent par préférence d'équipe
# PNPM est le plus moderne et efficace

15.2 Bun - Le Nouveau Sniper

La Révolution Bun

// Bun n'est pas juste un gestionnaire de paquets
// C'est un TOUT-EN-UN :
// 1. Runtime JavaScript (remplace Node.js)
// 2. Gestionnaire de paquets (remplace npm/yarn)
// 3. Bundler (remplace Webpack/Rollup)
// 4. Runner de tests (remplace Jest/Vitest)
// 5. Tout ça en étant incroyablement rapide

// Écrit en Zig, pas en JavaScript
// Démarrage quasi-instantané
// Compatible avec la majorité des paquets npm

Installation

# macOS/Linux
curl -fsSL https://bun.sh/install | bash

# Windows (WSL requis pour l'instant)
powershell -c "irm bun.sh/install.ps1 | iex"

# Vérifier
bun --version

Commandes Bun

# Runtime (comme Node)
bun run index.js
bun index.js          # Plus court

# Gestion de paquets
bun add lodash        # Installer (rapide comme l'éclair)
bun remove lodash
bun update

# Scripts
bun run dev
bun test              # Test runner intégré
bun lint

# Bundling
bun build ./index.js --outdir ./dist

# Créer un projet
bun create vite my-app
bun create next-app

Avantages de Bun

// 1. VITESSE (10-100x plus rapide que npm/yarn)
// 2. Tout-en-un (un seul outil à apprendre)
// 3. Node.js compatible (la plupart des paquets marchent)
// 4. TypeScript natif (pas besoin de transpilation)
// 5. Watch mode intelligent

// Exemple : bunx (comme npx mais plus rapide)
bunx create-react-app my-app
bunx vitest

// Mais attention :
// - Encore jeune (quelques bugs)
// - Pas toutes les fonctionnalités de l'écosystème mature
// - Communauté plus petite

Fichier bun.lockb

// Contrairement à package-lock.json (JSON lisible)
// bun.lockb est binaire (plus petit, plus rapide à parser)
// Ne pas éditer manuellement

15.3 Vite - Le Transporteur

Le Problème que Vite Résout

// Avant Vite (Webpack) :
// 1. Tu changes un fichier
// 2. Webpack reconstruit TOUT le bundle
// 3. Attente de 3 à 30 secondes
// 4. Le navigateur recharge la page
// 5. Tu perds ton état

// Avec Vite :
// 1. Tu changes un fichier
// 2. Vite rebuild juste ce fichier (ESM natif)
// 3. Hot Module Replacement (HMR) en <100ms
// 4. L'état de l'app est préservé
// 5. Tu gardes ta concentration

Installation

# Avec NPM
npm create vite@latest my-app
cd my-app
npm install
npm run dev

# Avec Bun
bun create vite my-app
cd my-app
bun install
bun run dev

Structure d'un Projet Vite

my-app/
├── index.html                # Point d'entrée (au root !)
├── package.json
├── vite.config.js           # Configuration
│
├── public/                  # Assets copiés tels quels
│   └── favicon.ico
│
└── src/                     # Code source
    ├── main.js              # Point d'entrée JS
    ├── style.css
    ├── App.jsx
    └── assets/              # Assets importés et transformés

Configuration Vite

// vite.config.js
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { resolve } from 'path';

export default defineConfig({
  plugins: [react()],
  
  // Alias pour les imports
  resolve: {
    alias: {
      '@': resolve(__dirname, 'src'),
      '@components': resolve(__dirname, 'src/components')
    }
  },
  
  // Server de développement
  server: {
    port: 3000,
    open: true,               // Ouvre le navigateur
    host: true,               // Accessible en réseau
    proxy: {                  // Proxy pour éviter les CORS
      '/api': {
        target: 'http://localhost:8080',
        changeOrigin: true
      }
    }
  },
  
  // Build
  build: {
    outDir: 'dist',
    sourcemap: true,          // Pour le debugging en prod
    rollupOptions: {
      output: {
        // Code splitting
        manualChunks: {
          vendor: ['react', 'react-dom'],
          utils: ['lodash', 'axios']
        }
      }
    }
  },
  
  // Preview (après build)
  preview: {
    port: 4173
  }
});

Fonctionnalités Clés

// 1. HMR (Hot Module Replacement)
// Le module est remplacé à chaud, pas de rechargement

// 2. ES Modules natifs en dev
// Pas de bundling en développement

// 3. Import d'assets
import logo from './assets/logo.svg'
import Worker from './worker.js?worker'  // Web Worker
import style from './style.css?inline'   // CSS en ligne

// 4. Variables d'environnement
// .env.local
VITE_API_KEY=secret_123

// Dans le code
console.log(import.meta.env.VITE_API_KEY)

// 5. Pré-processeurs natifs
// .scss, .sass, .less, .stylus supportés sans config

Plugins Vite

// Écosystème riche de plugins
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import eslint from 'vite-plugin-eslint';
import { VitePWA } from 'vite-plugin-pwa';

export default defineConfig({
  plugins: [
    vue(),
    eslint(),
    VitePWA({
      registerType: 'autoUpdate',
      manifest: {
        name: 'Mon App',
        short_name: 'App'
      }
    })
  ]
});

Vite vs Autres Bundlers

# Webpack
# + Très mature, énorme écosystème
# + Configuration ultra-flexible
# - Complexe à configurer
# - Lent en dev

# Parcel
# + Zéro configuration
# + Rapide
# - Moins flexible

# Rollup
# + Excellent pour les librairies
# + Arbre de dépendances propre
# - Moins bon pour les apps

# Vite
# + Extrêmement rapide en dev
# + Configuration simple mais puissante
# + Écosystème en croissance rapide
# - Plus jeune, moins de plugins matures

15.4 L'Arsenal Complet - Un Setup Moderne

Setup TypeScript avec Vite

# Créer le projet
npm create vite@latest my-app -- --template vanilla-ts

# Structure générée :
src/
├── main.ts
├── style.css
├── vite-env.d.ts    // Types pour import.meta.env
└── counter.ts

ESLint + Prettier

// .eslintrc.json
{
  "extends": [
    "eslint:recommended",
    "plugin:@typescript-eslint/recommended"
  ],
  "parser": "@typescript-eslint/parser",
  "plugins": ["@typescript-eslint"],
  "root": true,
  "rules": {
    "no-console": "warn",
    "prefer-const": "error"
  }
}

// .prettierrc
{
  "semi": true,
  "singleQuote": true,
  "trailingComma": "es5"
}

// package.json scripts
"scripts": {
  "lint": "eslint src/ --fix",
  "format": "prettier --write src/"
}

Vitest pour les Tests

// vitest.config.js
import { defineConfig } from 'vitest/config';
import { resolve } from 'path';

export default defineConfig({
  test: {
    globals: true,            // Pas besoin d'importer describe/it/expect
    environment: 'jsdom',     // Pour tester le DOM
    coverage: {
      provider: 'v8',
      reporter: ['text', 'html']
    }
  },
  resolve: {
    alias: {
      '@': resolve(__dirname, 'src')
    }
  }
});

Scripts NPM Complets

{
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview",
    "test": "vitest",
    "test:ui": "vitest --ui",
    "test:coverage": "vitest --coverage",
    "lint": "eslint src/ --ext .ts,.tsx,.js,.jsx --fix",
    "format": "prettier --write \"src/**/*.{ts,tsx,js,jsx,css,md}\"",
    "type-check": "tsc --noEmit",
    "prepare": "husky install"
  }
}

Git Hooks avec Husky

# Installation
npm install husky --save-dev
npm pkg set scripts.prepare="husky install"
npm run prepare

# Ajouter un hook pre-commit
npx husky add .husky/pre-commit "npm run lint && npm run test"

Docker (Optionnel)

# Dockerfile
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

15.5 Choix d'Outils - Selon la Mission

Pour une Petite App / Prototype

# Bun seul (le plus simple, le plus rapide)
bun create vite my-app
cd my-app
bun install
bun run dev

# Avantages :
# - Une seule dépendance
# - Démarrage instantané
# - Pas de configuration

# Inconvénients :
# - Écosystème plus petit
# - Risque de bugs (encore jeune)

Pour une App de Production (Équipe)

# NPM + Vite + TypeScript (stack moderne solide)
npm create vite@latest my-app -- --template react-ts
cd my-app
npm install
npm run dev

# Ajouter :
npm install -D eslint prettier husky vitest

# Avantages :
# - Stack éprouvée
# - Grande communauté
# - Beaucoup de ressources

# Inconvénients :
# - Plus de fichiers de config
# - Plus lent que Bun (mais vite quand même)

Pour une Librairie

# NPM + Vite (ou Rollup) pour le build
npm init -y
npm install -D vite @vitejs/plugin-library

# vite.config.js configuré pour library mode
# Avec export des types TypeScript

# Avantages :
# - Bundle optimisé pour les libs
# - Support TypeScript natif
# - Tree-shaking propre

Pour un Projet Existant (Legacy)

# Garder NPM/Yarn (stabilité)
# Ajouter Vite progressivement si possible
# Ou utiliser Bun pour accélérer les scripts

# Commandes bun compatibles :
bun install        # Lit package.json existant
bun run dev        # Exécute les scripts existants

15.6 Dépannage - Quand Ça Casse

Problèmes Courants

# Node modules corrompus
rm -rf node_modules package-lock.json
npm install

# Version Node incorrecte
nvm use 18  # Ou utiliser Volta/fnm

# Erreurs de permission (Linux/Mac)
sudo chown -R $USER:$USER node_modules

# Cache Vite problématique
rm -rf node_modules/.vite

# Bun qui plante
bun install --force  # Réinstalle tout

Debugging des Builds

// Dans vite.config.js
export default defineConfig({
  build: {
    minify: false,      // Désactiver la minification
    sourcemap: true,    // Générer des source maps
    rollupOptions: {
      output: {
        manualChunks(id) {
          // Voir comment le code est split
          console.log('Chunk:', id);
        }
      }
    }
  }
});

// Voir la taille du bundle
npm install -D rollup-plugin-visualizer
// Ajouter au config Vite

Performance

# Analyser le bundle
npx vite-bundle-analyzer

# Voir les dépendances lentes
npm install --timing

# Bun pour la vitesse
bun install  # 10x plus rapide que npm
bun run dev  # Démarrage en ms

Résumé du Module 15 :

NPM :

  • Le vieux sage, stable, immense écosystème
  • package.json pour la configuration
  • npm install pour tout installer
  • SemVer pour la gestion des versions

Bun :

  • Le nouveau sniper, extrêmement rapide
  • Tout-en-un : runtime, package manager, bundler, test runner
  • Compatible npm, TypeScript natif
  • Encore jeune mais prometteur

Vite :

  • Le transporteur moderne
  • Développement ultra-rapide avec HMR
  • Configuration simple mais puissante
  • Meilleur choix pour les nouvelles apps

Le stack moderne recommandé :

Pour une nouvelle app : Vite + TypeScript + Vitest
Package manager : Bun si tu veux la vitesse, NPM si tu veux la stabilité
Linting : ESLint + Prettier
Git hooks : Husky

La philosophie : Choisis tes outils comme tu choisis tes armes.
Certaines sont lourdes mais fiables.
D'autres légères mais moins éprouvées.
Connais leurs forces, connais leurs faiblesses.
Et surtout, sache quand changer d'arme.