Czym dokładnie jest wymiana modułu na gorąco w pakiecie internetowym?

245

Przeczytałem kilka stron na temat wymiany modułu na gorąco w pakiecie internetowym.
Jest nawet przykładowa aplikacja, która z niej korzysta .

Przeczytałem to wszystko i wciąż nie mam pojęcia.

Co mogę z tym zrobić?

  1. Czy ma to być wykorzystywane tylko w rozwoju, a nie w produkcji?
  2. Czy to jak LiveReload, ale musisz sam nim zarządzać?
  3. Czy WebpackDevServer jest w jakiś sposób zintegrowany z LiveReload?

Załóżmy, że chcę zaktualizować mój CSS (jeden arkusz stylów) i moduły JS podczas zapisywania ich na dysku, bez ponownego ładowania strony i bez używania wtyczek takich jak LiveReload. Czy jest to coś, co może pomóc w wymianie modułu na gorąco? Jaki rodzaj pracy muszę wykonać i co HMR już zapewnia?

Dan Abramov
źródło
HMR z Webpack jest prawie tak dobry jak ten: medium.com/@the1mills/…
Alexander Mills,

Odpowiedzi:

408

Najpierw chcę zauważyć, że wymiana modułu na gorąco (HMR) jest nadal funkcją eksperymentalną.

HMR to sposób wymiany modułów w uruchomionej aplikacji (oraz dodawanie / usuwanie modułów). Zasadniczo możesz aktualizować zmienione moduły bez pełnego ponownego ładowania strony.

Dokumentacja

Wymagania wstępne:

To nie tyle dla HMR, ale tutaj są linki:

Dodam te odpowiedzi do dokumentacji.

Jak to działa?

Z widoku aplikacji

Kod aplikacji prosi środowisko wykonawcze HMR o sprawdzenie dostępności aktualizacji. Środowisko wykonawcze HMR pobiera aktualizacje (asynchronicznie) i informuje kod aplikacji, że aktualizacja jest dostępna. Kod aplikacji prosi środowisko wykonawcze HMR o zastosowanie aktualizacji. Środowisko wykonawcze HMR stosuje aktualizacje (synchronizację). Kod aplikacji może, ale nie musi wymagać interakcji użytkownika w tym procesie (Ty decydujesz).

Z widoku kompilatora (webpack)

Oprócz zwykłych zasobów kompilator musi emitować „Aktualizację”, aby umożliwić aktualizację z poprzedniej wersji do tej wersji. „Aktualizacja” składa się z dwóch części:

  1. manifest aktualizacji (json)
  2. jeden lub wiele fragmentów aktualizacji (js)

Manifest zawiera nowy skrót kompilacji i listę wszystkich porcji aktualizacji (2).

Części aktualizacji zawierają kod wszystkich zaktualizowanych modułów w tej części (lub flagę, jeśli moduł został usunięty).

Kompilator dodatkowo upewnia się, że identyfikatory modułów i porcji są spójne między tymi kompilacjami. Wykorzystuje plik json „Records” do przechowywania ich między kompilacjami (lub przechowuje je w pamięci).

Z widoku modułu

HMR jest funkcją opcjonalną, więc wpływa tylko na moduły zawierające kod HMR. Dokumentacja opisuje interfejs API dostępny w modułach. Ogólnie rzecz biorąc, twórca modułu zapisuje procedury obsługi, które są wywoływane, gdy aktualizowana jest zależność tego modułu. Mogą także napisać moduł obsługi, który jest wywoływany podczas aktualizacji tego modułu.

W większości przypadków napisanie kodu HMR w każdym module nie jest obowiązkowe. Jeśli moduł nie ma modułów obsługi HMR, aktualizacja rośnie. Oznacza to, że pojedynczy moduł obsługi może obsłużyć aktualizacje pełnego drzewa modułów. Jeśli pojedynczy moduł w tym drzewie jest aktualizowany, całe drzewo modułów jest ponownie ładowane (tylko ponownie ładowane, nie przesyłane).

Z widoku środowiska wykonawczego HMR (techniczne)

Emitowany jest dodatkowy kod dla środowiska wykonawczego systemu modułów do śledzenia modułu parentsi children.

Po stronie zarządzania środowisko wykonawcze obsługuje dwie metody: checki apply.

checkRobi żądanie HTTP do manifestu aktualizacji. Gdy to żądanie nie powiedzie się, aktualizacja nie jest dostępna. W przeciwnym razie lista zaktualizowanych porcji jest porównywana z listą aktualnie załadowanych porcji. Dla każdego załadowanego fragmentu pobierany jest odpowiedni fragment aktualizacji. Wszystkie aktualizacje modułów są przechowywane w środowisku wykonawczym jako aktualizacje. Środowisko wykonawcze przełącza się w readystan, co oznacza, że ​​aktualizacja została pobrana i jest gotowa do zastosowania.

Dla każdego nowego żądania porcji w stanie gotowym pobierana jest również porcja aktualizacji.

Ta applymetoda oznacza wszystkie zaktualizowane moduły jako nieprawidłowe. Dla każdego niepoprawnego modułu musi istnieć moduł obsługi aktualizacji w module lub moduł obsługi aktualizacji w każdym module nadrzędnym. Podnieś nieprawidłowe bąbelki i oznacz również wszystkich rodziców jako nieprawidłowe. Proces ten trwa do momentu, gdy nie będzie już więcej „bąbelków”. Jeśli bąbelkuje do punktu wejścia, proces kończy się niepowodzeniem.

Teraz wszystkie nieprawidłowe moduły są usuwane (moduł obsługi) i rozładowywane. Następnie bieżący skrót jest aktualizowany i wywoływane są wszystkie programy obsługi „Akceptuj”. Środowisko wykonawcze przełącza się z powrotem do idlestanu i wszystko przebiega normalnie.

wygenerowane porcje aktualizacji

Co mogę z tym zrobić?

Możesz użyć go w fazie rozwoju jako zamiennika LiveReload. W rzeczywistości serwer webpack-dev-server obsługuje tryb gorący, który próbuje zaktualizować HMR przed próbą przeładowania całej strony. Musisz tylko dodać webpack/hot/dev-serverpunkt wejścia i wywołać serwer deweloperów za pomocą --hot.

Możesz go również użyć w produkcji jako mechanizmów aktualizacji. Tutaj musisz napisać własny kod zarządzania, który integruje HMR z Twoją aplikacją.

Niektóre programy ładujące już generują moduły, które można aktualizować na gorąco. np. style-loadermoże wymieniać arkusz stylów. Nie musisz robić nic specjalnego.

Załóżmy, że chcę zaktualizować mój CSS (jeden arkusz stylów) i moduły JS podczas zapisywania ich na dysku, bez ponownego ładowania strony i bez używania wtyczek takich jak LiveReload. Czy jest to coś, co może pomóc w wymianie modułu na gorąco?

tak

Jaki rodzaj pracy muszę wykonać i co HMR już zapewnia?

Oto mały przykład: https://webpack.js.org/guides/hot-module-replacement/

Moduł można zaktualizować tylko wtedy, gdy go „zaakceptujesz”. Potrzebujesz więc module.hot.acceptmodułu w rodzicach lub rodzicach rodziców ... np. Router to dobre miejsce lub podsłuch.

Jeśli chcesz go używać tylko z serwerem webpack-dev-server, po prostu dodaj webpack/hot/dev-serverjako punkt wejścia. W przeciwnym razie potrzebujesz kodu zarządzającego HMR, który wywołuje checki apply.

Opinia: Co sprawia, że ​​jest tak fajny?

  • To LiveReload, ale dla każdego rodzaju modułu.
  • Możesz go użyć w produkcji.
  • Aktualizacje są zgodne z podziałem kodu i pobierają aktualizacje tylko dla używanych części aplikacji.
  • Możesz go używać w części aplikacji i nie wpływa to na inne moduły
  • Jeśli HMR jest wyłączony, cały kod HMR jest usuwany przez kompilator (zawija go if(module.hot)).

Ostrzeżenia

  • Jest eksperymentalny i nie jest tak dobrze przetestowany.
  • Spodziewaj się kilku błędów.
  • Teoretycznie przydatny w produkcji, ale może być za wcześnie, aby użyć go do czegoś poważnego.
  • Identyfikatory modułów muszą być śledzone między kompilacjami, więc musisz je przechowywać ( records).
  • Optymalizator nie może już optymalizować identyfikatorów modułów po pierwszej kompilacji. Nieznaczny wpływ na rozmiar pakietu.
  • Kod środowiska wykonawczego HMR zwiększa rozmiar pakietu.
  • W przypadku zastosowania produkcyjnego wymagane są dodatkowe testy w celu przetestowania procedur obsługi HMR. To może być dość trudne.
Tobias K.
źródło
145
Cholerna odpowiedź.
Dan Abramov
13
Jeszcze raz dziękuję za wyjaśnienie. Zrobiłem film pokazujący moc HMR do edycji aplikacji React na żywo.
Dan Abramov
1
całkiem fajnie ... Pomyślałem o stworzeniu modułu ładującego z reakcją, który dodaje ładowanie HMR i asynchroniczne do reagowania komponentów.
Tobias K.
4
Skopiowałem tę odpowiedź do dokumentacji: webpack.github.io/docs/hot-module-replacement-with-webpack.html
Tobias K.
2
Błędy można wychwycić w zaktualizowanych modułach po zawinięciu modułu requireobsługi aktualizacji HMR w blok try-catch.
Tobias K.
10

Przyjęta odpowiedź wyjaśnia wszystko poprawnie. Poniższy opis pomaga szybko zrozumieć, czym jest HMR.

Wymiana modułu na gorąco jest jedną z najnowszych technik opracowywania javascript, która przyciąga uwagę programistów. Pomaga w rozwoju, zmniejszając liczbę odświeżeń stron, zastępując moduły zmianami w czasie wykonywania.

Podczas przeszukiwania HMR znalazłem artykuł wyjaśniający koncepcję w Internecie, którą możesz pobrać tutaj i dodając obraz GIF, który wyjaśnia tę koncepcję bez większego wyjaśnienia.

Tutaj działa - zwróć uwagę, że licznik czasu nie resetuje się do 0, tak jak po przeładowaniu strony, a css zmienia również automatyczne odświeżanie. Gorący moduł wymiany GIF

Webpack pomaga osiągnąć HMR. Dokumenty można znaleźć tutaj

Pomaga osiągnąć następujące

  • Zachowaj stan aplikacji utracony podczas pełnego ponownego ładowania.

  • Oszczędzaj cenny czas programowania, aktualizując tylko to, co się zmieniło.

  • Szybsze dostosowywanie stylów - prawie porównywalne ze zmieniającymi się stylami w debuggerze przeglądarki.

Oto przewodnik po pakiecie internetowym, aby osiągnąć HMR

samuelj90
źródło