Wymiana gorącego modułu w Redux

Opublikowany: 2022-03-11

Jest to minimalny przykład wymiany modułu na gorąco (lub HMR) w aplikacji Redux. Działający kod demonstracyjny jest hostowany na GitHub. Uwzględniamy tylko te ustawienia, które są niezbędne do obsługi HMR, dzięki czemu możesz łatwo zastosować HMR we własnej aplikacji Redux.

Jeśli nie możesz się doczekać zastosowania HMR, przejdź do tej sekcji, aby skonfigurować HMR dla swojego projektu w ciągu pięciu minut!

Demonstracja wymiany gorącego modułu

Uruchom przykład

Najpierw ubrudź sobie ręce! Zanim uruchomisz polecenia uruchamiające tę przykładową aplikację, upewnij się, że Git, Node.js i Yarn są poprawnie zainstalowane na Twoim komputerze.

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

Następnie odwiedź http://localhost:3000/, aby sprawdzić, czy to działa.

Po napisaniu kodu wymiana modułu na gorąco jest w stanie zaktualizować stronę bez pełnego odświeżenia. Co ważniejsze, stan Redux jest zachowywany, podczas gdy inne zasoby zostały zaktualizowane.

Wymiana gorącego modułu

Wymiana modułów na gorąco to jedna z najbardziej przydatnych funkcji oferowanych przez Webpack. Umożliwia aktualizację wszystkich rodzajów modułów, w tym plików JSON, CSS i JS, w czasie wykonywania bez konieczności pełnego odświeżania.

Oto jak to działa wewnętrznie:

  1. Aplikacja prosi środowisko wykonawcze HMR o sprawdzenie dostępności aktualizacji.
  2. Środowisko wykonawcze asynchronicznie pobiera aktualizacje i powiadamia aplikację.
  3. Następnie aplikacja prosi środowisko wykonawcze o zastosowanie aktualizacji.
  4. Środowisko wykonawcze synchronicznie stosuje aktualizacje.

Schemat wymiany gorącego modułu

HMR zwiększa produktywność podczas tworzenia aplikacji Redux. Redux to przewidywalny kontener stanu dla aplikacji JavaScript. To bardzo popularny, nowoczesny framework oparty na React. Redux, zgodnie z definicją pierwszej zasady Redux, jest pojedynczym współdzielonym magazynem danych, opisanym w dokumentacji jako „Pojedyncze źródło prawdy”. Magazyn danych (zwykły obiekt JavaScript aktualizowany przez reducers ) będzie aktualizowany w miarę obsługi aplikacji przez użytkownika. Każda operacja użytkownika, taka jak kliknięcie przycisku, ładowanie danych zaplecza itp., prawdopodobnie spowoduje wielokrotną aktualizację sklepu. Nie jest łatwo naprawić błąd, gdy błąd występuje tylko z określoną migawką stanu.

HMR pozwala nam aktualizować stronę bez ponownej inicjalizacji globalnego sklepu. Podczas opracowywania Redux możemy chcieć sprawdzić sklep po serii operacji. Bardzo częstym scenariuszem jest to, że błąd pojawia się dopiero po dodaniu konkretnego (być może złożonego) przedmiotu do sklepu. Bez HMR musimy wykonać następujące kroki:

  1. Zmodyfikuj kod, który potencjalnie powoduje błąd.
  2. Odśwież stronę, dodaj konkretną pozycję do sklepu.
  3. Jeśli błędy nadal występują, powtórz krok 1.

Powyższa iteracja będzie powtarzana raz za razem, jeśli błąd będzie trudny do znalezienia. W prawdziwym świecie błąd może pojawić się dopiero po jeszcze większej liczbie operacji. HMR pomaga nam skompilować i zastosować zmodyfikowany kod, zachowując obecną wartość sklepu bez zmian. Nie musimy powtarzać kroku 2. To zwiększa efektywność rozwoju.

Naprawienie błędu nie oznacza, że ​​musisz ponownie uruchomić aplikację za pomocą HMR.

Uwaga: W niektórych przypadkach modyfikacja kodu może wpłynąć na bieżącą wartość sklepu. W takim przypadku HMR ostrzeże Cię o ponownym załadowaniu całej strony.

Funkcja w tym przykładzie

Chcemy, aby funkcja była minimalna, tylko po to, aby zademonstrować możliwości HMR. Tak więc w tej aplikacji nie włączamy wspólnych funkcji w aplikacji React, w tym redux-logger, retrieve-router-redux, redux-thunk, redux-devtools itp. Tymczasem zachowujemy tylko jeden reduktor, dwie akcje i 1 strona.

Nasza aplikacja przechowuje tylko stan licznika w sklepie. Mamy tylko jedną stronę o nazwie home , która wyświetla wartość licznika i dwa przyciski do zwiększania/zmniejszania wartości licznika.

Aby potwierdzić, że HMR działa, wystarczy kilkakrotnie zwiększyć/zmniejszyć licznik, a następnie zmodyfikować kod. Na przykład zmień tytuł Licznik na Licznik w sklepie . Wtedy stwierdzimy, że:

  • Strona nie jest odświeżana.
  • Wyświetlana wartość licznika NIE JEST ZMIENIONA.
  • Tytuł został zmieniony na Licznik w sklepie .

‍ Skonfiguruj HMR w pięć minut

Aby skonfigurować HMR, wykonaj następujące kroki.

Biblioteki podstawowe

Te biblioteki muszą być zainstalowane, aby obsługiwać HMR:

  • React-hot-loader@^4.2.0: Kompiluj i aktualizuj aplikację React w czasie rzeczywistym.
  • webpack-dev-server@^3.1.4: obsługuje aplikację Webpack. Aktualizuje przeglądarkę po zmianach.

ES6

Jeśli używasz ECMAScript6 (kto nie jest w dzisiejszych czasach?), potrzebujesz więcej narzędzi do kompilacji ES6 w czasie rzeczywistym. Po pierwsze, jest to minimalny plik konfiguracyjny ES6 .babelrc:

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

Do obsługi kompilacji w czasie rzeczywistym potrzebna jest ta biblioteka:

  • babel-preset-react-hmre@^1.1.1

Webpack.config.js

Musimy skonfigurować HMR w pliku konfiguracyjnym Webpack webpack.config.js.

Najpierw włącz wtyczkę HMR w sekcji wtyczek:

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

Wtyczka HMR generuje Manifest, plik JSON zawierający listę zaktualizowanych modułów oraz Update, plik JSON zawierający dane do zastosowania. Należy zauważyć, że HMR jest opcją dostarczaną przez Webpack. Programy ładujące, takie jak style-loader, które implementują interfejs HMR, otrzymują aktualizację przez HMR, a następnie zastępują stary kod nowym kodem.

Jeśli używamy webpack-dev-server, to musimy włączyć hot flagę w sekcji devServer:

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

Gorące przeładowanie reduktorów Redux

Począwszy od wersji Redux 2.0.0, reduktory nie są niejawnie ponownie ładowane na gorąco, ponieważ niejawne ponowne ładowanie na gorąco powoduje pewne problemy. Jeśli stan Redux jest resetowany do wartości początkowych po aktualizacji na gorąco, spróbuj włączyć aktualizację na gorąco dla reduktorów:

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

Zaawansowane ustawienia

Więcej zaawansowanych ustawień HMR można znaleźć w interfejsie HMR API.

Biegać

Na koniec uruchom aplikację za pomocą:

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

Rozwiązywanie problemów

HMR po prostu nie stosuje zmian

HMR może zawieść po cichu bez żadnych ostrzeżeń. Kiedy aktualizujesz kod i zapisujesz, strona po prostu w ogóle się nie aktualizuje. Dzieje się tak prawdopodobnie dlatego, że twój system nie pozwala na oglądanie tak wielu zmian w plikach.

W Ubuntu możesz uruchomić sysctl -a | grep inotify sysctl -a | grep inotify , aby wyświetlić bieżącą wartość user.max_inotify_watches . Spróbuj zwiększyć tę liczbę, uruchamiając: sudo sysctl fs.inotify.max_user_watches=524288 . Alternatywnie dodaj nową linię fs.inotify.max_user_watches=524288 do pliku sudo vim /etc/sysctl.conf , a następnie uruchom sudo sysctl -p /etc/sysctl.conf , aby zastosować zmianę.