import() en JavaScript : charger un module seulement au moment utile

import() charge un module pendant l'exécution et renvoie une promesse. C'est l'outil du chargement à la demande et du découpage d'une application en morceaux.
3 min de lecture
Believemy logo

Une application charge souvent du code que la plupart des visiteurs n'exécuteront jamais : l'éditeur de texte riche, le générateur de PDF, la vue d'administration. Tout cela pèse au premier affichage, pour rien.

La forme import() permet de repousser ce chargement jusqu'à l'instant précis où le code devient nécessaire.


Définition

L'import dynamique est un appel de fonction, import(chemin), qui charge un module pendant l'exécution et renvoie une Promise. Cette promesse est tenue avec un objet contenant tous les exports du module, l'export par défaut compris sous la clé default.

JAVASCRIPT
// panier.js
export const TVA = 0.2;
export default function totalTTC(ht) {
  return ht * (1 + TVA);
}

// app.js
const panier = await import('./panier.js');

console.log(Object.keys(panier)); // [ 'TVA', 'default' ]
console.log(panier.default(100)); // 120

La Destructuration rend l'appel plus lisible : const { default: totalTTC, TVA } = await import('./panier.js').


Ce que le chargement à la demande change

Un Bundler (empaqueteur) traite chaque import() comme une frontière : le module et ses dépendances partent dans un fichier séparé, téléchargé seulement quand la ligne s'exécute. C'est le découpage en morceaux, et c'est souvent le gain de performance le plus rentable d'un projet.

JAVASCRIPT
bouton.addEventListener('click', async () => {
  const { ouvrirEditeur } = await import('./editeur.js');
  ouvrirEditeur();
});

Le même mécanisme sert à charger un fichier de traduction selon la langue choisie, ou une bibliothèque de graphiques uniquement sur la page qui en affiche.

Bon à savoir

Contrairement à un import classique, import() s'écrit n'importe où : dans une condition, dans une fonction, dans un gestionnaire d'événement. C'est justement ce que la forme statique interdit.


Trois pièges à connaître

  • Un chemin entièrement variable casse l'analyse. Les outils ont besoin d'en deviner la forme : préférez import(`./langues/${code}.js`), dont la partie fixe reste lisible, à un chemin construit de bout en bout.
  • La promesse peut être rompue. Un fichier absent ou une coupure réseau provoquent un rejet, à traiter avec try et catch sous peine d'interface figée.
  • Le module reste en cache. Dix appels sur le même chemin ne téléchargent le fichier qu'une fois, inutile de mémoriser le résultat vous-même.


Questions fréquentes

Question

Faut-il toujours écrire await devant import() ?

Non, c'est simplement la forme la plus lisible. import('./x.js').then(...) fait exactement le même travail, et convient quand le code environnant n'est pas une fonction async. Dans un module ES, await est également accepté au niveau supérieur du fichier.


Question

Peut-on l'utiliser dans un fichier CommonJS ?

Oui, et c'est même le pont officiel entre les deux mondes : import() fonctionne dans un fichier CommonJS et sait charger un Module ES, là où require() échoue. La contrepartie est que le résultat arrive de façon asynchrone.


Question

Quand ce découpage devient-il contre-productif ?

Quand les morceaux sont trop petits ou trop nombreux : chaque fichier séparé coûte une requête, et découper un module de deux kilo-octets ne rapporte rien. Réservez la technique aux blocs vraiment lourds ou vraiment rares, et mesurez avant de généraliser.

Termes connexes

Découvrez notre glossaire JavaScript

Tous les mots de JavaScript expliqués simplement : mots-clés, objets natifs, méthodes, erreurs et concepts. Définitions claires et exemples qui tournent, pour apprendre et pour se dépanner.

Partager cet article

Tu veux nous aider ? Fais un lien vers cet article sur tes réseaux ou encore mieux : sur ton site, dans un article ou dans ta newsletter.