熱模組替換

熱模組替換 (HMR) 在應用程式執行期間交換、新增或移除模組,而無需完全重新載入。這可以在幾個方面顯著加快開發速度

  • 保留在完全重新載入期間遺失的應用程式狀態。
  • 只更新已變更的部分,節省寶貴的開發時間。
  • 當在原始碼中修改 CSS/JS 時,立即更新瀏覽器,這幾乎等同於直接在瀏覽器的開發人員工具中變更樣式。

運作方式

讓我們從不同的觀點來了解 HMR 的運作方式...

在應用程式中

以下步驟允許在應用程式中交換模組

  1. 應用程式要求 HMR 執行時間檢查更新。
  2. 執行時間非同步下載更新並通知應用程式。
  3. 然後,應用程式要求執行時間套用更新。
  4. 執行時間同步套用更新。

您可以設定 HMR 以自動執行此程序,或者您可以選擇要求使用者互動才能進行更新。

在編譯器中

除了正常的資產外,編譯器還需要發出「更新」以允許從舊版本更新到新版本。「更新」包含兩個部分

  1. 已更新的 清單 (JSON)
  2. 一個或多個已更新的區塊 (JavaScript)

清單包含新的編譯雜湊和所有已更新區塊的清單。每個區塊都包含所有已更新模組的新程式碼 (或標示模組已移除的旗標)。

編譯器確保模組 ID 和區塊 ID 在這些建置之間一致。它通常將這些 ID 儲存在記憶體中 (例如使用 webpack-dev-server),但也可以將它們儲存在 JSON 檔案中。

在模組中

HMR 是一個選擇性加入的功能,只會影響包含 HMR 程式碼的模組。一個範例是透過 style-loader 修補樣式。為了讓修補生效,style-loader 實作 HMR 介面;當它透過 HMR 收到更新時,它會用新的樣式取代舊的樣式。

類似地,在模組中實作 HMR 介面時,您可以說明模組更新時應該發生什麼事。但是,在大部分情況下,不必在每個模組中撰寫 HMR 程式碼。如果模組沒有 HMR 處理常式,更新會向上傳遞。這表示單一處理常式可以更新完整的模組樹。如果樹中的單一模組更新,整個依賴項集合會重新載入。

請參閱 HMR API 頁面,以取得關於 module.hot 介面的詳細資料。

在執行時期

這裡會變得更技術性一點...如果您對內部運作沒有興趣,請隨時跳到 HMR API 頁面HMR 指南

對於模組系統執行時期,會發出額外的程式碼來追蹤模組的parentschildren。在管理方面,執行時期支援兩個方法:checkapply

check會對更新清單提出 HTTP 要求。如果此要求失敗,則表示沒有可用的更新。如果成功,則會將更新區塊清單與目前已載入區塊清單進行比較。對於每個已載入區塊,會下載對應的更新區塊。所有模組更新都會儲存在執行時期中。當所有更新區塊都已下載完畢且準備好套用時,執行時期會切換到ready狀態。

apply方法會將所有已更新模組標記為無效。對於每個無效模組,在模組或其父項中需要有一個更新處理常式。否則,無效旗標會冒泡並使父項也無效。每個冒泡會持續到到達應用程式的進入點或具有更新處理常式的模組(以先達到的為準)。如果從進入點冒泡,則處理程序會失敗。

之後,所有無效模組都會被處置(透過處置處理常式)並卸載。然後會更新目前的雜湊,並呼叫所有accept處理常式。執行時期會切換回idle狀態,所有事項都會繼續正常運作。

開始使用

HMR 可以用於開發中,作為 LiveReload 的替換。 webpack-dev-server 支援hot模式,在嘗試重新載入整個頁面之前,它會嘗試使用 HMR 進行更新。請參閱 熱模組替換指南 以取得詳細資訊。

6 貢獻者

kryptokinghtSpaceK33zsokraGRardBrouzbeh84skipjack