Hot Module Replacement (HMR) : fonctionnement
Le Hot Module Replacement (HMR) remplace les modules modifiés d'une appli en cours sans rechargement et garde l'état. Fonctionnement dans Vite et webpack.
Qu'est-ce que le Hot Module Replacement (HMR) ?
Le Hot Module Replacement (HMR) remplace, ajoute ou supprime des modules dans une application en cours d'exécution sans recharger toute la page. Un serveur de développement envoie le module modifié au navigateur, qui exécute la nouvelle version et, quand c'est possible, conserve l'état, comme une saisie de formulaire ou la route courante. C'est un outil de développement, pas une fonction de production.
Comment fonctionne le HMR
Le bundler ou le serveur de développement surveille les fichiers et garde une connexion avec la page, en général un WebSocket. À l'enregistrement, il ne recompile que ce qui a changé et envoie une mise à jour. Dans webpack, le compilateur produit un manifeste mis à jour et les chunks modifiés, que le runtime HMR télécharge et applique. Dans Vite, le serveur sert des modules ES natifs : le navigateur ne ré-importe que le module modifié.
Le HMR doit savoir jusqu'où une mise à jour peut remonter. Un module qui gère ses propres mises à jour est une frontière HMR. Si le module modifié ne l'accepte pas, la mise à jour remonte vers les modules qui l'importent. Si elle atteint le point d'entrée sans être acceptée, elle échoue et le serveur recharge toute la page. Les frameworks s'en occupent pour vous (React Fast Refresh, composants monofichiers de Vue), on l'écrit donc rarement à la main.
Exemple : un module Vite qui accepte les mises à jour
// counter.js
let timer = setInterval(tick, 1000)
if (import.meta.hot) {
import.meta.hot.accept()
import.meta.hot.dispose(() => clearInterval(timer))
}Sans le gestionnaire dispose, chaque enregistrement lancerait un nouvel intervalle en plus de l'ancien. Vite documente cette API sur vite.dev ; l'entourer d'un if (import.meta.hot) permet de l'éliminer des builds de production par tree-shaking.
HMR, live reload et rechargement complet
- Rechargement complet : la page est jetée et tous les scripts se relancent, l'état est perdu.
- Live reload : recharge l'onglet automatiquement à chaque enregistrement, mais reste un rechargement complet.
- HMR : ne remplace que les modules modifiés, l'état survit le plus souvent, et un changement de CSS n'exige aucun rechargement.
Erreurs fréquentes
- Pas de nettoyage. Les minuteurs, écouteurs et abonnements lancés à l'import s'accumulent à chaque mise à jour si aucun gestionnaire dispose ne les retire.
- S'appuyer sur l'état au niveau du module. Les valeurs de la portée du module peuvent être réinitialisées, et le comportement diffère d'un chargement neuf.
- Ignorer les rechargements complets inattendus. Ils signalent souvent qu'aucun module au-dessus n'accepte la mise à jour.
- Se fier aux temps de développement. Une appli avec HMR actif n'est pas celle que reçoivent vos utilisateurs.
HMR, tests et supervision
Le HMR ne fait que raccourcir la boucle de modification. Il ne dit rien du comportement du build de production, dont le runtime HMR ne fait pas partie. Vérifiez le vrai bundle dans un build proche de la production : le Largest Contentful Paint et les autres Core Web Vitals d'une application monopage dépendent de ce que vous livrez, pas de la vitesse à laquelle vous itérez. Notre guide sur les performances JavaScript explique quoi mesurer, et la surveillance de la vitesse des pages le suit régulièrement une fois le site en ligne.
Questions fréquentes sur le Hot Module Replacement
Le HMR, est-ce la même chose que le live reload ?
Non. Le live reload recharge toute la page et perd l'état. Le HMR ne remplace que les modules modifiés dans la page en cours et garde le plus souvent l'état. Quand il ne peut pas appliquer un changement sans risque, il retombe sur un rechargement complet.
Le HMR tourne-t-il en production ?
Non. Il appartient au serveur de développement. Les builds de production n'incluent pas le runtime HMR, et l'API de Vite est conçue pour pouvoir en être retirée.
Pourquoi mon appli se recharge-t-elle entièrement malgré le HMR ?
Le module modifié et tous ceux au-dessus n'ont pas accepté la mise à jour, qui a atteint le point d'entrée. Cherchez des effets de bord à l'import ou un changement d'exports non pris en charge.
Quels outils prennent en charge le HMR ?
webpack et Vite le prennent en charge, et les frameworks ajoutent leurs propres couches, comme React Fast Refresh et le HMR des composants monofichiers de Vue. La plupart des modèles de démarrage l'activent par défaut.
Le HMR conserve-t-il l'état des composants ?
Souvent, mais au mieux, sans garantie. Modifier l'état au niveau du module ou la forme d'un composant peut le réinitialiser ou provoquer un rechargement complet.
Termes associés
Outils LoadFocus connexes
Mettez ce concept en pratique avec LoadFocus, la plateforme même qui propulse tout ce que vous venez de lire.