Zunächst möchte ich darauf hinweisen, dass der Hot Module Replacement (HMR) immer noch eine experimentelle Funktion ist.
HMR ist eine Möglichkeit, Module in einer laufenden Anwendung auszutauschen (und Module hinzuzufügen / zu entfernen). Grundsätzlich können Sie geänderte Module ohne erneutes Laden der gesamten Seite aktualisieren.
Dokumentation
Voraussetzungen:
Es ist nicht so sehr für HMR, aber hier sind die Links:
Ich werde diese Antworten zur Dokumentation hinzufügen.
Wie funktioniert es?
Aus der App-Ansicht
Der App-Code fordert die HMR-Laufzeit auf, nach Updates zu suchen. Die HMR-Laufzeit lädt die Updates herunter (asynchron) und teilt dem App-Code mit, dass ein Update verfügbar ist. Der App-Code fordert die HMR-Laufzeit auf, Aktualisierungen anzuwenden. Die HMR-Laufzeit wendet die Aktualisierungen an (Synchronisierung). Der App-Code erfordert möglicherweise eine Benutzerinteraktion in diesem Prozess (Sie entscheiden).
In der Compiler-Ansicht (Webpack)
Zusätzlich zu den normalen Assets muss der Compiler das "Update" ausgeben, um ein Update von einer früheren Version auf diese Version zu ermöglichen. Das "Update" besteht aus zwei Teilen:
- das Update-Manifest (json)
- ein oder mehrere Update-Chunks (js)
Das Manifest enthält den neuen Kompilierungs-Hash und eine Liste aller Update-Chunks (2).
Die Aktualisierungsblöcke enthalten Code für alle aktualisierten Module in diesem Block (oder ein Flag, wenn ein Modul entfernt wurde).
Der Compiler stellt außerdem sicher, dass die Modul- und Chunk-IDs zwischen diesen Builds konsistent sind. Es verwendet eine json-Datei "records", um sie zwischen Builds zu speichern (oder speichert sie im Speicher).
Aus der Modulansicht
HMR ist eine Opt-In-Funktion und betrifft daher nur Module, die HMR-Code enthalten. In der Dokumentation wird die API beschrieben, die in Modulen verfügbar ist. Im Allgemeinen schreibt der Modulentwickler Handler, die aufgerufen werden, wenn eine Abhängigkeit dieses Moduls aktualisiert wird. Sie können auch einen Handler schreiben, der aufgerufen wird, wenn dieses Modul aktualisiert wird.
In den meisten Fällen muss nicht in jedem Modul HMR-Code geschrieben werden. Wenn ein Modul keine HMR-Handler hat, sprudelt das Update. Dies bedeutet, dass ein einzelner Handler Aktualisierungen für einen vollständigen Modulbaum verarbeiten kann. Wenn ein einzelnes Modul in diesem Baum aktualisiert wird, wird der gesamte Modulbaum neu geladen (nur neu geladen, nicht übertragen).
Aus der HMR-Laufzeitansicht (technisch)
Zusatzcode ist für die Modul Systemlaufzeit ausgesendeten Modul zu verfolgen parents
und children
.
Auf der Verwaltungsseite unterstützt die Laufzeit zwei Methoden: check
und apply
.
A check
führt eine HTTP-Anforderung an das Aktualisierungsmanifest durch. Wenn diese Anforderung fehlschlägt, ist kein Update verfügbar. Andernfalls wird die Liste der aktualisierten Chunks mit der Liste der aktuell geladenen Chunks verglichen. Für jeden geladenen Block wird der entsprechende Update-Block heruntergeladen. Alle Modulaktualisierungen werden zur Laufzeit als Aktualisierungen gespeichert. Die Laufzeit wechselt in den ready
Status, dh ein Update wurde heruntergeladen und kann angewendet werden.
Für jede neue Blockanforderung im Bereitschaftszustand wird auch der Aktualisierungsblock heruntergeladen.
Die apply
Methode kennzeichnet alle aktualisierten Module als ungültig. Für jedes ungültige Modul muss ein Update-Handler im Modul oder Update-Handler in jedem übergeordneten Modul vorhanden sein. Andernfalls sprudelt das Ungültige und markiert auch alle Eltern als ungültig. Dieser Vorgang wird fortgesetzt, bis kein "Aufblasen" mehr auftritt. Wenn es bis zu einem Einstiegspunkt sprudelt, schlägt der Prozess fehl.
Jetzt werden alle ungültigen Module entsorgt (Entsorgungshandler) und entladen. Dann wird der aktuelle Hash aktualisiert und alle "Accept" -Handler werden aufgerufen. Die Laufzeit wechselt wieder in den idle
Zustand und alles läuft normal weiter.
Was kann ich damit machen?
Sie können es in der Entwicklung als LiveReload-Ersatz verwenden. Tatsächlich unterstützt der Webpack-Dev-Server einen Hot-Modus, der versucht, mit HMR zu aktualisieren, bevor versucht wird, die gesamte Seite neu zu laden. Sie müssen nur den webpack/hot/dev-server
Einstiegspunkt hinzufügen und den Dev-Server mit aufrufen --hot
.
Sie können es auch in der Produktion als Aktualisierungsmechanismen verwenden. Hier müssen Sie Ihren eigenen Verwaltungscode schreiben, der HMR in Ihre App integriert.
Einige Lader generieren bereits Module, die im laufenden Betrieb aktualisiert werden können. zB Die style-loader
können das Stylesheet austauschen. Sie müssen nichts Besonderes tun.
Angenommen, ich möchte meine CSS- (ein Stylesheet-) und JS-Module aktualisieren, wenn ich sie auf der Festplatte speichere, ohne die Seite neu zu laden und ohne Plugins wie LiveReload zu verwenden. Kann mir Hot Module Replacement dabei helfen?
Ja
Welche Art von Arbeit muss ich tun und was bietet HMR bereits an?
Hier ein kleines Beispiel: https://webpack.js.org/guides/hot-module-replacement/
Ein Modul kann nur aktualisiert werden, wenn Sie es "akzeptieren". Sie müssen also module.hot.accept
das Modul in den Eltern oder den Eltern der Eltern ... zB Ein Router ist ein guter Ort oder eine Unteransicht.
Wenn Sie es nur mit dem Webpack-Dev-Server verwenden möchten, fügen Sie es einfach webpack/hot/dev-server
als Einstiegspunkt hinzu. Andernfalls benötigen Sie einen HMR-Verwaltungscode, der check
und aufruft apply
.
Meinung: Was macht es so cool?
- Es ist LiveReload, aber für jede Modulart.
- Sie können es in der Produktion verwenden.
- Die Updates berücksichtigen Ihre Code-Aufteilung und laden nur Updates für die verwendeten Teile Ihrer App herunter.
- Sie können es für einen Teil Ihrer Anwendung verwenden und es wirkt sich nicht auf andere Module aus
- Wenn HMR deaktiviert ist, wird der gesamte HMR-Code vom Compiler entfernt (einpacken
if(module.hot)
).
Vorsichtsmaßnahmen
- Es ist experimentell und nicht so gut getestet.
- Erwarten Sie einige Fehler.
- Theoretisch in der Produktion verwendbar, aber es kann zu früh sein, um es für etwas Ernstes zu verwenden.
- Die Modul-IDs müssen zwischen den Kompilierungen verfolgt werden, damit Sie sie speichern können (
records
).
- Der Optimierer kann die Modul-IDs nach der ersten Kompilierung nicht mehr optimieren. Ein kleiner Einfluss auf die Bundle-Größe.
- HMR-Laufzeitcode erhöht die Bundle-Größe.
- Für den Produktionseinsatz sind zusätzliche Tests erforderlich, um die HMR-Handler zu testen. Das könnte ziemlich schwierig sein.