0 XP
?
Intermédiaire35 min25 XP

Objectifs de cette leçon

  • Exporter des fonctions et variables
  • Importer des modules
  • Comprendre les named vs default exports

Modules ES en JavaScript 📦

Les modules permettent de decouper un projet en fichiers independants, reutilisables et bien organises. C'est la base de tout projet JavaScript moderne.


1. Pourquoi des modules ? 🤔

Sans modules, tous les scripts partagent le meme scope global :

// ❌ Sans modules — tout est global
// fichier1.js
var data = "bonjour"; // Variable globale !

// fichier2.js
var data = "au revoir"; // Ecrase la precedente !

💡 Les modules isolent chaque fichier. Ce qui est defini dans un module reste prive sauf s'il est explicitement exporte.


2. Export nomme (named exports) 🏷️

// utils.js
export const PI = 3.14159;

export function carrer(x) {
    return x * x;
}

export function cube(x) {
    return x * x * x;
}

export class Personne {
    constructor(nom) {
        this.nom = nom;
    }
    saluer() {
        return `Bonjour, je suis ${this.nom}`;
    }
}

3. Export par defaut (default export) 🌟

Chaque module ne peut avoir qu'UN SEUL export par defaut :

// Calculatrice.js
export default class Calculatrice {
    additionner(a, b) { return a + b; }
    soustraire(a, b) { return a - b; }
    multiplier(a, b) { return a * b; }
    diviser(a, b) {
        if (b === 0) throw new Error("Division par zero !");
        return a / b;
    }
}

4. Importer des modules 📥

// Importer un export nomme
import { PI, carrer } from "./utils.js";
console.log(PI);          // 3.14159
console.log(carrer(5));   // 25

// Importer avec alias
import { PI as PiConstante } from "./utils.js";
console.log(PiConstante);

// Importer l'export par defaut
import Calculatrice from "./Calculatrice.js";
const calc = new Calculatrice();
console.log(calc.additionner(2, 3)); // 5

// Importer tout dans un namespace
import * as Utils from "./utils.js";
console.log(Utils.PI);
console.log(Utils.carrer(5));

// Importer sans nommer (side-effect only)
import "./monStyle.css";

5. Comparaison des types d'import/export 📊

TypeExportImportUtilisation
Nommeexport const x = 5import { x } from "./mod"Fonctions, classes, constantes
Par defautexport default class X {}import X from "./mod"Un seul element principal
Toutexport { a, b }import * as X from "./mod"Namespace

6. Module pattern — avant les modules natifs 📜

Avant ES6, on utilisait ce pattern pour isoler le code :

// IIFE Module Pattern
const MonModule = (function() {
    let prive = "je suis prive";

    function methodPublique() {
        return prive;
    }

    return {
        methodPublique
    };
})();

console.log(MonModule.methodPublique()); // "je suis prive"
console.log(MonModule.prive);            // undefined

7. Import dynamique ⚡

import() est une fonction qui retourne une promesse. Utile pour le lazy loading :

// Charger un module uniquement quand c'est necessaire
bouton.addEventListener("click", async () => {
    const module = await import("./LourdModule.js");
    module.default();
});

// Chargement conditionnel
if (condition) {
    const { fonction } = await import("./ModuleConditionnel.js");
    fonction();
}

// Router : charger la page au moment du clic
async function chargerPage(nomPage) {
    const { default: page } = await import(`./pages/${nomPage}.js`);
    return page;
}

💡 L'import dynamique est ideal pour optimiser les performances : on ne charge que ce dont on a besoin.


8. Organisation de modules dans un projet 📁

src/
├── main.js               // Point d'entree
├── modules/
│   ├── utils.js          // Fonctions utilitaires
│   ├── Calculatrice.js   // Classe Calculatrice
│   ├── personne.js       // Gestion des personnes
│   └── api.js            // Appels reseau
├── composants/
│   ├── Header.js
│   ├── Footer.js
│   └── Modal.js
└── styles/
    └── global.css
// main.js
import { PI } from "./modules/utils.js";
import Calculatrice from "./modules/Calculatrice.js";
import Header from "./composants/Header.js";

const calc = new Calculatrice();
const header = new Header();

9. Bonnes pratiques 📏

PratiqueRaison
Un module = une responsabiliteFacilite la maintenance
Export par defaut pour les classesConvention courante
Noms de fichiers en camelCasemonModule.js
Toujours specifier l'extensionimport x from "./mod.js"
Groupement logiquecomposants/, modules/, utils/
Eviter les side effectsUn module ne devrait pas modifier l'etat global
Utiliser des noms explicitesfetchUtilisateurs plutot que fetch

10. Exercices pour toi 🎯

Exercice 1 : Creer un module Cree un module math.js avec des fonctions additionner, soustraire, multiplier, diviser et importe-les dans main.js.

Exercice 2 : Lazy loading Implemente le chargement dynamique d'un composant quand l'utilisateur clique sur un bouton.

Exercice 3 : Refactoring Transforme un fichier monolithique en plusieurs modules bien organises.

⚡ Simulateur — Modules

Étape 1/6
📝 Pseudo-code
1// math.js
2export function add(a, b) { return a + b; }
3export const PI = 3.14;
4// main.js
5import { add, PI } from "./math.js";
6console.log(add(2, 3));
⚙️ Exécution
📦 Mémoire
Aucune variable
🔀 Flux d'exécution
math.js
3
Fichier module

// math.js est un commentaire montrant qu'on est dans le fichier math.js. Les modules JS séparent le code en fichiers distincts.