Organiser son code avec les modules ES
Notions théoriques
Qu'est-ce qu'un module ES ?
Un module ES (ES Module) est un fichier JavaScript qui peut exporter des fonctions, des variables ou des classes, et les importer dans d'autres fichiers.
Avant les modules, tout le code JavaScript d'une page était dans un seul fichier ou dans des scripts chargés globalement, ce qui rendait la maintenance difficile.
Les modules permettent de :
- découper le code en fichiers spécialisés
- réutiliser des fonctions dans plusieurs endroits
- éviter les conflits de noms de variables entre fichiers
Exporter depuis un module
Il existe deux façons d'exporter :
Export nomm é — on exporte plusieurs éléments avec leur nom :
// utils.js
export function additionner(a, b) {
return a + b
}
export function multiplier(a, b) {
return a * b
}
export const PI = 3.14159
Export par défaut — on exporte un seul élément principal du fichier :
// calculatrice.js
export default function calculer(a, b, operation) {
if (operation === '+') return a + b
if (operation === '-') return a - b
return 0
}
Importer dans un autre fichier
Importer un export nommé (accolades obligatoires) :
// main.js
import { additionner, multiplier } from './utils.js'
console.log(additionner(3, 4)) // 7
console.log(multiplier(3, 4)) // 12
Importer un export par défaut (pas d'accolades, nom libre) :
// main.js
import calculer from './calculatrice.js'
console.log(calculer(10, 5, '+')) // 15
Importer tout d'un module sous un alias :
import * as utils from './utils.js'
console.log(utils.additionner(3, 4)) // 7
console.log(utils.PI) // 3.14159
Vite et les modules
Vite traite nativement les ES Modules en développement : chaque import est résolu directement par le navigateur. Au moment du build (npm run build), Vite regroupe tous les modules en un ou plusieurs fichiers optimisés (bundling).
counter.js du projet vanillaLe projet Vite vanilla généré par défaut contient déjà un exemple de module : src/counter.js exporte une fonction setupCounter utilisée dans src/main.js. C'est un bon exemple à étudier.
Règles importantes
| Règle | Explication |
|---|---|
| Chemin relatif obligatoire | './utils.js' et non 'utils.js' |
Extension .js recommandée | Toujours préciser .js pour les imports locaux |
| Un seul export default par fichier | Plusieurs exports nommés possibles |
| Imports en haut de fichier | Par convention, tous les imports sont au début |
Exemple pratique
Voici comment organiser un projet Vite avec deux modules :
src/utils.js — module utilitaire :
export function saluer(prenom) {
return `Bonjour, ${prenom} !`
}
export function majuscules(texte) {
return texte.toUpperCase()
}
src/main.js — point d'entrée qui importe le module :
import './style.css'
import { saluer, majuscules } from './utils.js'
const message = saluer('Alice')
const messageMaj = majuscules(message)
document.querySelector('#app').innerHTML = `
<div>
<h1>${message}</h1>
<p>${messageMaj}</p>
</div>`
Si vous oubliez les accolades autour d'un export nommé (import saluer from './utils.js' au lieu de import { saluer } from './utils.js'), vous obtiendrez undefined ou une erreur. Les accolades sont obligatoires pour les exports nommés.
Test de mémorisation/compréhension
TP pour réfléchir et résoudre des problèmes
Dans ce TP, vous allez créer un projet Vite et l'organiser en plusieurs modules : un module de calcul, un module d'affichage, et le point d'entrée principal.
Étape 1 — Créer le projet
Créez un nouveau projet Vite vanilla :
npm create vite@latest tp-modules
# Vanilla → JavaScript
cd tp-modules
npm install
npm run dev
Utilisez des tirets et des minuscules pour nommer vos projets npm (tp-modules, mon-projet). Les espaces et les majuscules sont déconseillés dans les noms de packages npm.
Étape 2 — Créer le module de calcul
Créez le fichier src/calcul.js avec deux fonctions exportées :
Un bon module fait une seule chose bien. calcul.js gère le calcul, pas l'affichage. Cette séparation rend le code plus facile à tester et à réutiliser dans d'autres projets.
Étape 3 — Créer le module d'affichage
Créez le fichier src/affichage.js avec une fonction par défaut :
Utilisez export default pour la fonction principale d'un module et les exports nommés pour les fonctions secondaires. Cela indique aux autres développeurs ce qui est le plus important dans ce fichier.
Étape 4 — Assembler dans main.js
Importez les deux modules dans src/main.js et utilisez-les :
Vous pouvez importer des exports nommés et un export default depuis des fichiers différents dans le même main.js. Gardez tous les imports en haut du fichier, regroupés par module source.