Chapitre 19 – Modules JavaScript

Les modules permettent d'organiser le code JavaScript en plusieurs fichiers afin de le rendre plus clair, réutilisable et maintenable. Chaque module peut exporter des variables, fonctions ou classes, et importer ce dont il a besoin d'un autre module.

Zone de démonstration interactive

Les résultats des opérations avec les modules apparaîtront ici...
ES6 Modules
CommonJS

Démonstration des imports/exports avec les modules ES6

Démonstration des require/exports avec CommonJS (simulé)

1. Fichiers modules (import / export)

Export nommé
Export par défaut

Export nommé

Permet d'exporter plusieurs valeurs depuis un module. L'import doit utiliser les mêmes noms entre accolades.

// fichier utils.js
export const PI = 3.14159;
export function addition(a, b) {
  return a + b;
}
export class Calculatrice {
  // ...
}

Importation :

// fichier main.js
import { PI, addition, Calculatrice } from './utils.js';

console.log(PI); // 3.14159
console.log(addition(2, 3)); // 5
const calc = new Calculatrice();

Export par défaut

Permet d'exporter une seule valeur principale depuis un module. L'import peut utiliser n'importe quel nom.

// fichier math.js
export default function multiply(a, b) {
  return a * b;
}

// Alternative pour une classe
// export default class Multiplicateur { ... }

Importation :

// fichier app.js
import multiply from './math.js';
// ou avec un nom différent
import multiplicateur from './math.js';

console.log(multiply(3, 4)); // 12

2. Portée des modules

Les modules JavaScript ont leur propre portée. Les variables définies dans un module ne sont pas visibles globalement, sauf si elles sont explicitement exportées. Cela évite les conflits de noms et rend le code plus sécurisé.

// module.js
const secret = "Je suis privé"; // Non exporté → inaccessible de l'extérieur
export const publicVar = "Je suis public"; // Exporté → accessible

// main.js
import { publicVar } from './module.js';
console.log(publicVar); // OK
console.log(secret); // Erreur: secret n'est pas défini

De plus, le strict mode ("use strict") est automatiquement activé dans les modules, ce qui interdit certaines mauvaises pratiques comme l'utilisation de variables non déclarées.

3. Modules ES6 vs CommonJS

ES6 Modules
CommonJS

Modules ES6 (modernes)

  • Utilisent import et export.
  • Sont compatibles avec les navigateurs modernes.
  • Sont statiquement analysables (permet l'optimisation lors du build).
  • Supportent les imports asynchrones avec import().
// export
export const x = 42;
export function hello() { return "Bonjour"; }
export default class Person { /* ... */ }

// import
import { x, hello } from './module.js';
import Person from './module.js';

CommonJS (ancien standard, surtout pour Node.js)

  • Utilisent require() et module.exports.
  • Ne sont pas compatibles avec les navigateurs sans outil de build (comme Webpack).
  • Sont évalués dynamiquement au moment de l'exécution.
  • Encapsulation moins stricte que les modules ES6.
// fichier util.js
module.exports = function(a, b) {
  return a + b;
};

// fichier app.js
const addition = require('./util');
console.log(addition(2, 3));

4. Utilisation dans un navigateur

Pour utiliser des modules ES6 dans un navigateur, ajoutez type="module" à la balise <script> :

<!-- Fichier HTML -->
<script type="module" src="main.js"></script>

Important :

5. Import dynamique

Les modules peuvent être chargés dynamiquement avec la fonction import() qui retourne une promesse :

// Chargement dynamique d'un module
button.addEventListener('click', async () => {
  const module = await import('./module.js');
  module.doSomething();
});

Utile pour :

Résumé du chapitre

  • Les modules permettent d'organiser le code en fichiers séparés, avec leurs propres portées.
  • Les modules ES6 utilisent export / import et sont nativement pris en charge par les navigateurs modernes.
  • Les modules CommonJS utilisent require / module.exports et sont principalement utilisés dans Node.js.
  • Chaque module est encapsulé : ses variables ne polluent pas l'espace global.
  • Les exports peuvent être nommés (plusieurs par module) ou par défaut (un seul par module).
  • L'import dynamique avec import() permet de charger des modules à la demande.

Comprendre les modules est fondamental pour structurer correctement une application JavaScript moderne.