Hot Module Replacement in Redux
Veröffentlicht: 2022-03-11Dies ist ein minimales Beispiel für Hot Module Replacement (oder HMR) in einer Redux-Anwendung. Der funktionierende Democode wird auf GitHub gehostet. Wir enthalten nur die Einstellungen, die für die Unterstützung von HMR erforderlich sind, sodass Sie HMR ganz einfach in Ihrer eigenen Redux-Anwendung anwenden können.
Wenn Sie es kaum erwarten können, HMR anzuwenden, gehen Sie zu diesem Abschnitt, um HMR innerhalb von fünf Minuten für Ihr Projekt einzurichten!
Führen Sie das Beispiel aus
Mach dir zuerst die Hände schmutzig! Bevor Sie die Befehle zum Starten dieser Beispielanwendung ausführen, stellen Sie bitte sicher, dass Git, Node.js und Yarn korrekt auf Ihrem Computer installiert sind.
$ git clone https://github.com/Front-end-io/articles.git $ cd articles && git checkout redux-hmr $ yarn install $ yarn start
Besuchen Sie dann http://localhost:3000/, um zu sehen, ob es funktioniert.
Nach dem Schreiben Ihres Codes kann Hot Module Replacement die Seite ohne vollständige Aktualisierung aktualisieren. Noch wichtiger ist, dass der Redux-Status beibehalten wird, während andere Ressourcen an Ort und Stelle aktualisiert wurden.
Hot-Modul-Ersatz
Hot Module Replacement ist eine der nützlichsten Funktionen von Webpack. Es ermöglicht die Aktualisierung aller Arten von Modulen, einschließlich JSON-, CSS- und JS-Dateien, zur Laufzeit, ohne dass eine vollständige Aktualisierung erforderlich ist.
So funktioniert es intern:
- Die Anwendung fordert die HMR-Laufzeit auf, nach Updates zu suchen.
- Die Laufzeit lädt die Updates asynchron herunter und benachrichtigt die Anwendung.
- Die Anwendung fordert dann die Laufzeit auf, die Aktualisierungen anzuwenden.
- Die Laufzeit wendet die Aktualisierungen synchron an.
HMR steigert die Produktivität bei der Entwicklung einer Redux-Anwendung. Redux ist ein vorhersagbarer Zustandscontainer für JavaScript-Apps. Es ist ein sehr beliebtes State-of-Art-Framework, das auf React basiert. Redux ist per Definition des ersten Redux-Prinzips ein singulärer gemeinsam genutzter Datenspeicher, der in seiner Dokumentation als „Single Source of Truth“ beschrieben wird. Der Datenspeicher (ein einfaches JavaScript-Objekt, das von reducers
aktualisiert wird) wird aktualisiert, wenn der Benutzer mit der Anwendung arbeitet. Jede Benutzeroperation, wie z. B. das Klicken auf eine Schaltfläche, das Laden von Back-End-Daten usw., wird den Store wahrscheinlich mehrmals aktualisieren. Es ist nicht einfach, einen Fehler zu beheben, wenn der Fehler nur mit einer bestimmten Momentaufnahme des Status auftritt.
HMR ermöglicht es uns, die Seite zu aktualisieren, ohne den globalen Speicher neu zu initialisieren. Während der Redux-Entwicklung möchten wir den Speicher möglicherweise nach einer Reihe von Vorgängen inspizieren. Ein sehr häufiges Szenario ist, dass ein Fehler erst auftritt, nachdem wir einen bestimmten (möglicherweise komplexen) Artikel zum Shop hinzugefügt haben. Ohne HMR müssen wir die folgenden Schritte ausführen:
- Ändern Sie den Code, der möglicherweise den Fehler verursacht.
- Aktualisieren Sie die Seite und fügen Sie den jeweiligen Artikel dem Geschäft hinzu.
- Wenn die Fehler bestehen bleiben, wiederholen Sie Schritt 1.
Die obige Iteration wird immer wieder wiederholt, wenn der Fehler schwer zu finden ist. In der realen Welt tritt der Fehler möglicherweise erst nach noch mehr Operationen auf. HMR hilft uns, den geänderten Code zu kompilieren und anzuwenden, während der aktuelle Speicherwert unverändert bleibt. Wir müssen Schritt 2 nicht wiederholen. Es steigert die Effizienz der Entwicklung.
Funktion in diesem Beispiel
Wir möchten das Feature minimal halten, nur um die HMR-Fähigkeit zu demonstrieren. In dieser Anwendung integrieren wir also keine gemeinsamen Funktionen in eine React-Anwendung, einschließlich Redux-Logger, React-Router-Redux, Redux-Thunk, Redux-Devtools usw. In der Zwischenzeit behalten wir nur einen Reducer, zwei Aktionen und 1 Seite.

Unsere Anwendung hält nur einen Gegenwert im Geschäft. Wir haben nur eine Seite namens home , die den Zählerwert und zwei Schaltflächen zum Erhöhen/Verringern des Zählerwerts anzeigt.
Um zu bestätigen, dass HMR funktioniert, erhöhen/verringern Sie einfach den Zähler mehrmals und ändern Sie dann einen Code. Ändern Sie beispielsweise den Titel Counter in Counter in store . Dann finden wir das:
- Die Seite wird nicht aktualisiert.
- Der angezeigte Zählerwert wird NICHT GEÄNDERT.
- Der Titel wurde in Counter in store geändert.
HMR in fünf Minuten einrichten
Befolgen Sie diese Schritte, um HMR einzurichten.
Wesentliche Bibliotheken
Diese Bibliotheken müssen installiert werden, um HMR zu unterstützen:
- React-Hot-Loader@^4.2.0: Kompilieren und aktualisieren Sie die React-Anwendung in Echtzeit.
- webpack-dev-server@^3.1.4: Stellt eine Webpack-App bereit. Aktualisiert den Browser bei Änderungen.
ES6
Wenn Sie ECMAScript6 verwenden (wer ist das heutzutage nicht?), benötigen Sie einige weitere Tools, um ES6 in Echtzeit zu kompilieren. Zunächst ist dies die minimale ES6-Konfigurationsdatei .babelrc:
{ "env": { "development": { "presets": [ "react-hmre" ] } } }
Zur Unterstützung der Echtzeitkompilierung wird diese Bibliothek benötigt:
- babel-preset-react-hmre@^1.1.1
Webpack.config.js
Wir müssen HMR in der Webpack-Konfigurationsdatei webpack.config.js konfigurieren.
Aktivieren Sie zunächst das HMR-Plugin im Plugin-Bereich:
"plugins": [ … new webpack.NamedModulesPlugin(), new webpack.HotModuleReplacementPlugin(), ]
Das HMR-Plugin generiert ein Manifest, eine JSON-Datei, die die aktualisierten Module auflistet, und ein Update, eine JSON-Datei, die die anzuwendenden Daten enthält. Zu beachten ist, dass HMR eine von Webpack bereitgestellte Option ist. Loader wie style-loader, die die HMR-Schnittstelle implementieren, erhalten ein Update über HMR und ersetzen dann den alten Code durch den neuen Code.
Wenn wir webpack-dev-server verwenden, müssen wir das Hot-Flag im Abschnitt devServer aktivieren:
"devServer": [ ... hot: true, ]
Laden Sie die Redux-Reduzierer im laufenden Betrieb neu
Ab der Redux-Version 2.0.0 werden die Reducer nicht implizit heiß neu geladen, da das implizite heiße Neuladen einige Probleme verursacht. Wenn Ihr Redux-Status beim Hot-Update auf die Anfangswerte zurückgesetzt wird, versuchen Sie, das Hot-Update für die Reducer zu aktivieren:
import { createStore } from 'redux'; import rootReducer from '../reducers/index'; export default function configureStore(initialState) { const store = createStore(rootReducer, initialState); if (module.hot) { // Enable Webpack hot module replacement for reducers module.hot.accept('../reducers', () => { const nextRootReducer = require('../reducers/index'); store.replaceReducer(nextRootReducer); }); } return store; }
Erweiterte Einstellungen
Weitere erweiterte Einstellungen von HMR finden Sie in der HMR-API.
Laufen
Abschließend führen Sie die Anwendung bitte aus mit:
$ ./node_modules/.bin/webpack-dashboard -- webpack-dev-server
Fehlerbehebung
HMR wendet die Änderungen einfach nicht an
HMR kann unbemerkt ohne Warnungen fehlschlagen. Wenn Sie den Code aktualisieren und speichern, wird die Seite einfach überhaupt nicht aktualisiert. Dies liegt wahrscheinlich daran, dass Ihr System es Ihnen nicht erlaubt, so viele Dateiänderungen zu beobachten.
Unter Ubuntu können Sie sysctl -a | grep inotify
ausführen sysctl -a | grep inotify
, um den aktuellen user.max_inotify_watches
Wert anzuzeigen. Versuchen Sie, diese Zahl zu erhöhen, indem Sie Folgendes ausführen: sudo sysctl fs.inotify.max_user_watches=524288
. Hängen Sie alternativ eine neue Zeile fs.inotify.max_user_watches=524288
an die Datei sudo vim /etc/sysctl.conf
und führen Sie dann sudo sysctl -p /etc/sysctl.conf
aus, um die Änderung zu übernehmen.