Wymiana gorącego modułu w Redux
Opublikowany: 2022-03-11Jest 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!
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:
- Aplikacja prosi środowisko wykonawcze HMR o sprawdzenie dostępności aktualizacji.
- Środowisko wykonawcze asynchronicznie pobiera aktualizacje i powiadamia aplikację.
- Następnie aplikacja prosi środowisko wykonawcze o zastosowanie aktualizacji.
- Środowisko wykonawcze synchronicznie stosuje aktualizacje.
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:
- Zmodyfikuj kod, który potencjalnie powoduje błąd.
- Odśwież stronę, dodaj konkretną pozycję do sklepu.
- 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.
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ę.