Remplacement de module à chaud dans Redux

Publié: 2022-03-11

Ceci est un exemple minimal de remplacement de module à chaud (ou HMR) dans une application Redux. Le code de démonstration fonctionnel est hébergé sur GitHub. Nous n'incluons que les paramètres essentiels pour prendre en charge HMR, ce qui vous permet d'appliquer facilement HMR dans votre propre application Redux.

Si vous ne pouvez pas attendre pour appliquer HMR, passez à cette section pour configurer HMR pour votre projet en cinq minutes !

Démonstration de remplacement de module à chaud

Exécutez l'exemple

Mettez d'abord vos mains dans le cambouis ! Avant d'exécuter les commandes pour démarrer cet exemple d'application, assurez-vous que Git, Node.js et Yarn sont correctement installés sur votre machine.

 $ git clone https://github.com/Front-end-io/articles.git $ cd articles && git checkout redux-hmr $ yarn install $ yarn start

Ensuite, visitez http://localhost:3000/ pour voir si cela fonctionne.

Lors de l'écriture de votre code, le remplacement de module à chaud est capable de mettre à jour la page sans actualisation complète. Plus important encore, l'état Redux est conservé tandis que d'autres ressources ont été mises à jour en place.

Remplacement du module à chaud

Le remplacement de module à chaud est l'une des fonctionnalités les plus utiles offertes par Webpack. Il permet à tous les types de modules, y compris les fichiers JSON, CSS et JS, d'être mis à jour au moment de l'exécution sans avoir besoin d'une actualisation complète.

Voici comment cela fonctionne en interne :

  1. L'application demande au runtime HMR de vérifier les mises à jour.
  2. Le runtime télécharge de manière asynchrone les mises à jour et notifie l'application.
  3. L'application demande alors au runtime d'appliquer les mises à jour.
  4. Le runtime applique les mises à jour de manière synchrone.

Schéma de remplacement du module à chaud

HMR augmente la productivité lors du développement d'une application Redux. Redux est un conteneur d'état prévisible pour les applications JavaScript. C'est un framework de pointe très populaire basé sur React. Redux, par définition du premier principe de Redux, est un magasin de données partagé singulier, décrit par sa documentation comme une « source unique de vérité ». Le magasin de données (un objet JavaScript simple mis à jour par les reducers ) sera mis à jour au fur et à mesure que l'utilisateur opère sur l'application. Chaque opération de l'utilisateur, telle que cliquer sur un bouton, charger des données back-end, etc., mettra probablement à jour le magasin plusieurs fois. Il n'est pas facile de corriger un bogue lorsque le bogue ne se produit qu'avec un instantané particulier de l'état.

HMR nous permet de mettre à jour la page sans réinitialiser le magasin global. Lors du développement de Redux, nous pouvons souhaiter inspecter le magasin après une série d'opérations. Un scénario très courant est qu'un bogue ne se produit qu'après avoir ajouté un article particulier (peut-être complexe) au magasin. Sans HMR, nous devons suivre les étapes suivantes :

  1. Modifiez le code qui cause potentiellement le bogue.
  2. Actualisez la page, ajoutez l'article particulier au magasin.
  3. Si les bogues persistent, répétez l'étape 1.

L'itération ci-dessus sera répétée encore et encore si le bogue est difficile à trouver. Dans le monde réel, le bogue peut n'apparaître qu'après encore plus d'opérations. HMR nous aide à compiler et à appliquer le code modifié tout en gardant la valeur actuelle du magasin inchangée. Nous n'avons pas besoin de répéter l'étape 2. Cela augmente l'efficacité du développement.

Corriger un bug ne signifie pas qu'il faille redémarrer l'application, avec HMR.

Remarque : Dans certains cas, la modification du code peut affecter la valeur actuelle du magasin. Dans ce cas, HMR vous avertira de recharger toute la page.

Fonctionnalité dans cet exemple

Nous voulons garder la fonctionnalité minimale, juste pour démontrer la capacité HMR. Ainsi, dans cette application, nous n'incorporons pas de fonctionnalités communes dans une application React, notamment redux-logger, react-router-redux, redux-thunk, redux-devtools, etc. En attendant, nous ne gardons qu'un réducteur, deux actions et 1 page.

Notre application ne conserve qu'une valeur de compteur dans le magasin. Nous n'avons qu'une seule page appelée home , qui affiche la valeur du compteur et deux boutons pour augmenter/diminuer la valeur du compteur.

Pour confirmer que HMR fonctionne, augmentez/diminuez simplement le compteur plusieurs fois, puis modifiez du code. Par exemple, modifiez le titre Comptoir à Comptoir en magasin . Nous trouverons alors que :

  • La page n'est pas actualisée.
  • La valeur du compteur affichée N'EST PAS MODIFIÉE.
  • Le titre a été changé en Comptoir en magasin .

‍ Configurer HMR en cinq minutes

Pour configurer HMR, procédez comme suit.

Bibliothèques essentielles

Ces bibliothèques doivent être installées pour prendre en charge HMR :

  • react-hot-loader@^4.2.0 : Compilez et mettez à jour l'application React en temps réel.
  • webpack-dev-server@^3.1.4 : sert une application Webpack. Met à jour le navigateur sur les changements.

ES6

Si vous utilisez ECMAScript6 (qui ne l'est pas ces jours-ci ?), vous avez besoin d'outils supplémentaires pour compiler ES6 en temps réel. Tout d'abord, voici le fichier de configuration minimal ES6 .babelrc :

 { "env": { "development": { "presets": [ "react-hmre" ] } } }

Pour prendre en charge la compilation en temps réel, cette bibliothèque est nécessaire :

  • babel-preset-react-hmre@^1.1.1

Webpack.config.js

Nous devons configurer HMR dans le fichier de configuration Webpack webpack.config.js.

Tout d'abord, activez le plugin HMR dans la section plugins :

 "plugins": [ … new webpack.NamedModulesPlugin(), new webpack.HotModuleReplacementPlugin(), ]

Le plugin HMR génère un Manifest, un fichier JSON listant les modules mis à jour, et un Update, un fichier JSON contenant les données à appliquer. Ce qu'il faut noter, c'est que HMR est une option fournie par Webpack. Les chargeurs comme style-loader, qui implémentent l'interface HMR, reçoivent une mise à jour via HMR, puis remplacent l'ancien code par le nouveau code.

Si nous utilisons webpack-dev-server, nous devons activer le hot flag dans la section devServer :

 "devServer": [ ... hot: true, ]

Recharger à chaud les réducteurs Redux

À partir de la version 2.0.0 de Redux, les réducteurs ne sont pas rechargés à chaud implicitement car le rechargement à chaud implicite pose certains problèmes. Si votre état Redux est réinitialisé aux valeurs initiales lors de la mise à jour à chaud, essayez d'activer la mise à jour à chaud pour les réducteurs :

 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; }

Réglages avancés

Pour des paramètres plus avancés de HMR, veuillez vous référer à l'API HMR.

Cours

Enfin, lancez l'application avec :

 $ ./node_modules/.bin/webpack-dashboard -- webpack-dev-server

Dépannage

L'HMR n'applique tout simplement pas les changements

HMR peut échouer silencieusement sans aucun avertissement. Lorsque vous mettez à jour le code et enregistrez, la page ne se met tout simplement pas à jour. C'est probablement parce que votre système ne vous permet pas de surveiller autant de modifications de fichiers.

Sur Ubuntu, vous pouvez exécuter sysctl -a | grep inotify sysctl -a | grep inotify pour afficher la valeur user.max_inotify_watches actuelle. Essayez d'augmenter ce nombre en exécutant : sudo sysctl fs.inotify.max_user_watches=524288 . Vous pouvez également ajouter une nouvelle ligne fs.inotify.max_user_watches=524288 au fichier sudo vim /etc/sysctl.conf , puis exécuter sudo sysctl -p /etc/sysctl.conf pour appliquer la modification.