Je veux d'abord noter que le remplacement de module à chaud (HMR) est toujours une fonctionnalité expérimentale.
HMR est un moyen d'échanger des modules dans une application en cours d'exécution (et d'ajouter / supprimer des modules). Vous pouvez essentiellement mettre à jour les modules modifiés sans recharger une page entière.
Documentation
Pré-requis:
Ce n'est pas tant pour HMR, mais voici les liens:
J'ajouterai ces réponses à la documentation.
Comment ça marche?
Depuis la vue de l'application
Le code d'application demande au runtime HMR de vérifier les mises à jour. Le runtime HMR télécharge les mises à jour (async) et indique au code de l'application qu'une mise à jour est disponible. Le code d'application demande au runtime HMR d'appliquer les mises à jour. Le runtime HMR applique les mises à jour (synchronisation). Le code d'application peut ou non nécessiter une interaction de l'utilisateur dans ce processus (vous décidez).
Depuis la vue du compilateur (webpack)
En plus des actifs normaux, le compilateur doit émettre la «mise à jour» pour permettre la mise à jour d'une version précédente vers cette version. La "mise à jour" comprend deux parties:
- le manifeste de mise à jour (json)
- un ou plusieurs morceaux de mise à jour (js)
Le manifeste contient le nouveau hachage de compilation et une liste de tous les morceaux de mise à jour (2).
Les blocs de mise à jour contiennent du code pour tous les modules mis à jour dans ce bloc (ou un indicateur si un module a été supprimé).
Le compilateur s'assure en outre que les identifiants de module et de bloc sont cohérents entre ces builds. Il utilise un fichier json "records" pour les stocker entre les builds (ou il les stocke en mémoire).
Depuis la vue du module
HMR est une fonctionnalité opt-in, elle n'affecte donc que les modules contenant du code HMR. La documentation décrit l'API disponible dans les modules. En général, le développeur de module écrit des gestionnaires qui sont appelés lorsqu'une dépendance de ce module est mise à jour. Ils peuvent également écrire un gestionnaire qui est appelé lorsque ce module est mis à jour.
Dans la plupart des cas, il n'est pas obligatoire d'écrire du code HMR dans chaque module. Si un module n'a pas de gestionnaires HMR, la mise à jour bouillonne. Cela signifie qu'un seul gestionnaire peut gérer les mises à jour pour une arborescence de modules complète. Si un seul module de cette arborescence est mis à jour, l'arborescence complète des modules est rechargée (uniquement rechargée, pas transférée).
Depuis la vue d'exécution HMR (technique)
Un code supplémentaire est émis pour l'exécution du système du module pour suivre le module parents
et children
.
Côté gestion, le runtime prend en charge deux méthodes: check
et apply
.
A check
fait une requête HTTP au manifeste de mise à jour. Lorsque cette demande échoue, aucune mise à jour n'est disponible. Sinon, la liste des morceaux mis à jour est comparée à la liste des morceaux actuellement chargés. Pour chaque bloc chargé, le bloc de mise à jour correspondant est téléchargé. Toutes les mises à jour du module sont stockées dans le runtime en tant que mises à jour. Le runtime passe à l' ready
état, ce qui signifie qu'une mise à jour a été téléchargée et est prête à être appliquée.
Pour chaque nouvelle demande de bloc à l'état prêt, le bloc de mise à jour est également téléchargé.
La apply
méthode marque tous les modules mis à jour comme non valides. Pour chaque module non valide, il doit y avoir un gestionnaire de mise à jour dans le module ou des gestionnaires de mise à jour dans chaque parent. Sinon, les bulles invalides apparaissent et marque tous les parents comme invalides également. Ce processus se poursuit jusqu'à ce qu'il n'y ait plus de «bulle». S'il bouillonne jusqu'à un point d'entrée, le processus échoue.
Maintenant, tous les modules invalides sont éliminés (gestionnaire d'élimination) et déchargés. Ensuite, le hachage actuel est mis à jour et tous les gestionnaires "acceptent" sont appelés. Le runtime revient à l' idle
état et tout se poursuit normalement.
Que puis-je en faire?
Vous pouvez l'utiliser en développement en remplacement de LiveReload. En fait, le webpack-dev-server prend en charge un mode à chaud qui essaie de mettre à jour avec HMR avant d'essayer de recharger la page entière. Il vous suffit d'ajouter le webpack/hot/dev-server
point d'entrée et d'appeler le serveur de développement avec --hot
.
Vous pouvez également l'utiliser en production comme mécanismes de mise à jour. Ici, vous devez écrire votre propre code de gestion qui intègre HMR à votre application.
Certains chargeurs génèrent déjà des modules pouvant être mis à jour à chaud. Par exemple, le style-loader
peut échanger la feuille de style. Vous n'avez rien à faire de spécial.
Supposons que je veuille mettre à jour mes modules CSS (une feuille de style) et JS lorsque je les enregistre sur le disque, sans recharger la page et sans utiliser de plugins tels que LiveReload. Est-ce quelque chose que le remplacement de module à chaud peut m'aider?
Oui
Quel type de travail dois-je faire et que fournit déjà HMR?
Voici un petit exemple: https://webpack.js.org/guides/hot-module-replacement/
Un module ne peut être mis à jour que si vous "l'acceptez". Vous devez donc module.hot.accept
le module dans les parents ou les parents des parents ... par exemple, un routeur est un bon endroit, ou une sous-vue.
Si vous voulez seulement l'utiliser avec le serveur webpack-dev-server, ajoutez simplement webpack/hot/dev-server
comme point d'entrée. Sinon, vous avez besoin d'un code de gestion HMR qui appelle check
et apply
.
Opinion: Qu'est-ce qui le rend si cool?
- C'est LiveReload mais pour chaque type de module.
- Vous pouvez l'utiliser en production.
- Les mises à jour respectent votre fractionnement de code et téléchargent uniquement les mises à jour pour les parties utilisées de votre application.
- Vous pouvez l'utiliser pour une partie de votre application et cela n'affecte pas les autres modules
- Si HMR est désactivé, tout le code HMR est supprimé par le compilateur (enveloppez-le
if(module.hot)
).
Avertissements
- C'est expérimental et pas si bien testé.
- Attendez-vous à quelques bugs.
- Théoriquement utilisable en production, mais il est peut-être trop tôt pour l'utiliser pour quelque chose de grave.
- Les ID de module doivent être suivis entre les compilations, vous devez donc les stocker (
records
).
- L'optimiseur ne peut plus optimiser les ID de module après la première compilation. Un peu d'impact sur la taille du bundle.
- Le code d'exécution HMR augmente la taille du bundle.
- Pour une utilisation en production, des tests supplémentaires sont nécessaires pour tester les gestionnaires HMR. Cela pourrait être assez difficile.