Sostituzione del modulo caldo in Redux

Pubblicato: 2022-03-11

Questo è un esempio minimo di sostituzione di moduli a caldo (o HMR) in un'applicazione Redux. Il codice demo funzionante è ospitato su GitHub. Includiamo solo quelle impostazioni essenziali per supportare l'HMR, semplificando l'applicazione dell'HMR nella tua applicazione Redux.

Se non vedi l'ora di applicare l'HMR, passa a questa sezione per configurare l'HMR per il tuo progetto entro cinque minuti!

Dimostrazione di sostituzione del modulo a caldo

Esegui l'esempio

Prima sporcati le mani! Prima di eseguire i comandi per avviare questa applicazione di esempio, assicurati che Git, Node.js e Yarn siano installati correttamente sul tuo computer.

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

Quindi visita http://localhost:3000/ per vedere se funziona.

Dopo aver scritto il codice, la sostituzione del modulo a caldo è in grado di aggiornare la pagina senza un aggiornamento completo. Ancora più importante, lo stato Redux viene mantenuto mentre altre risorse sono state aggiornate.

Sostituzione del modulo caldo

La sostituzione del modulo a caldo è una delle funzionalità più utili offerte da Webpack. Consente a tutti i tipi di moduli, inclusi i file JSON, CSS e JS, di essere aggiornati in fase di esecuzione senza che sia necessario un aggiornamento completo.

Ecco come funziona internamente:

  1. L'applicazione chiede al runtime HMR di verificare la presenza di aggiornamenti.
  2. Il runtime scarica gli aggiornamenti in modo asincrono e invia una notifica all'applicazione.
  3. L'applicazione chiede quindi al runtime di applicare gli aggiornamenti.
  4. Il runtime applica gli aggiornamenti in modo sincrono.

Schema di sostituzione del modulo caldo

HMR aumenta la produttività durante lo sviluppo di un'applicazione Redux. Redux è un contenitore di stato prevedibile per le app JavaScript. È un framework all'avanguardia molto popolare basato su React. Redux, per definizione del primo principio di Redux, è un singolo archivio di dati condiviso, descritto dalla sua documentazione come una "fonte di verità unica". L'archivio dati (un semplice oggetto JavaScript aggiornato da reducers ) verrà aggiornato man mano che l'utente opera sull'applicazione. Ogni operazione dell'utente, come fare clic su un pulsante, caricare dati di back-end e così via, probabilmente aggiornerà il negozio più volte. Non è facile correggere un bug quando il bug si verifica solo con una particolare istantanea dello stato.

HMR ci consente di aggiornare la pagina senza reinizializzare il negozio globale. Durante lo sviluppo di Redux, potremmo voler ispezionare il negozio dopo una serie di operazioni. Uno scenario molto comune è che un bug si verifica solo dopo aver aggiunto un articolo particolare (forse complesso) al negozio. Senza HMR, dobbiamo eseguire i seguenti passaggi:

  1. Modifica il codice che potenzialmente causa il bug.
  2. Aggiorna la pagina, aggiungi il particolare articolo al negozio.
  3. Se i bug persistono, ripetere il passaggio 1.

L'iterazione di cui sopra verrà ripetuta ancora e ancora se il bug è difficile da trovare. Nel mondo reale, il bug potrebbe apparire solo dopo ancora più operazioni. HMR ci aiuta a compilare e applicare il codice modificato mantenendo invariato il valore del negozio corrente. Non è necessario ripetere il passaggio 2. Aumenta l'efficienza dello sviluppo.

Correggere un bug non significa che devi riavviare l'applicazione, con HMR.

Nota: in alcuni casi, la modifica del codice può influire sul valore del negozio corrente. In tal caso, HMR ti avviserà di ricaricare l'intera pagina.

Caratteristica in questo esempio

Vogliamo mantenere la funzionalità minima, solo per dimostrare la capacità HMR. Quindi in questa applicazione, non incorporiamo funzionalità comuni in un'applicazione React, inclusi redux-logger, react-router-redux, redux-thunk, redux-devtools, ecc. Nel frattempo, manteniamo solo un riduttore, due azioni e 1 pagina.

La nostra applicazione mantiene solo un controvalore nel negozio. Abbiamo solo una pagina chiamata home , che mostra il valore del contatore e due pulsanti per aumentare/diminuire il valore del contatore.

Per confermare che HMR funziona, è sufficiente aumentare/diminuire il contatore più volte, quindi modificare del codice. Ad esempio, modifica il titolo Contatore in Contatore in negozio . Allora troveremo che:

  • La pagina non viene aggiornata.
  • Il valore del contatore visualizzato NON È CAMBIATO.
  • Il titolo è stato cambiato in Contatore in negozio .

‍ Configura HMR in cinque minuti

Per configurare l'HMR, attenersi alla seguente procedura.

Biblioteche essenziali

Queste librerie devono essere installate per supportare HMR:

  • react-hot-loader@^4.2.0: compila e aggiorna l'applicazione React in tempo reale.
  • webpack-dev-server@^3.1.4: serve un'app Webpack. Aggiorna il browser alle modifiche.

ES6

Se stai usando ECMAScript6 (chi non lo è, di questi tempi?), hai bisogno di altri strumenti per compilare ES6 in tempo reale. Innanzitutto, questo è il file di configurazione ES6 minimo .babelrc:

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

Per supportare la compilazione in tempo reale, è necessaria questa libreria:

  • babel-preset-react-hmre@^1.1.1

Webpack.config.js

È necessario configurare l'HMR nel file di configurazione di Webpack webpack.config.js.

Innanzitutto, abilita il plug-in HMR nella sezione plug-in:

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

Il plugin HMR genera un Manifest, un file JSON che elenca i moduli aggiornati, e un Update, un file JSON contenente i dati da applicare. Quello che va notato è che HMR è un'opzione fornita da Webpack. Caricatori come style-loader, che implementano l'interfaccia HMR, ricevono un aggiornamento tramite HMR e quindi sostituiscono il vecchio codice con il nuovo codice.

Se stiamo usando webpack-dev-server, allora dobbiamo attivare l'hot flag nella sezione devServer:

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

Ricarica a caldo i riduttori Redux

A partire da Redux versione 2.0.0, i riduttori non vengono ricaricati a caldo in modo implicito perché il ricaricamento a caldo implicito causa alcuni problemi. Se il tuo stato Redux viene ripristinato ai valori iniziali quando viene aggiornato a caldo, prova ad abilitare l'aggiornamento a caldo per i riduttori:

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

Impostazioni avanzate

Per impostazioni più avanzate di HMR, fare riferimento all'API HMR.

Correre

Infine, eseguire l'applicazione con:

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

Risoluzione dei problemi

HMR semplicemente non applica le modifiche

L'HMR potrebbe fallire silenziosamente senza alcun avviso. Quando aggiorni il codice e salvi, la pagina semplicemente non si aggiorna affatto. Ciò è probabilmente dovuto al fatto che il tuo sistema non ti consente di guardare così tante modifiche ai file.

Su Ubuntu, puoi eseguire sysctl -a | grep inotify sysctl -a | grep inotify per visualizzare il valore user.max_inotify_watches corrente. Prova ad aumentare questo numero eseguendo: sudo sysctl fs.inotify.max_user_watches=524288 . In alternativa, aggiungi una nuova riga fs.inotify.max_user_watches=524288 al file sudo vim /etc/sysctl.conf e quindi esegui sudo sysctl -p /etc/sysctl.conf per applicare la modifica.