模組熱替換(HMR)可以在應用程式執行過程中交換、新增或刪除模組,而無需完全重新載入。這可以在幾個方面顯著加快開發速度
讓我們從不同的角度來理解 HMR 的具體工作原理...
以下步驟允許模組在應用程式中進行替換
你可以設定 HMR 自動執行此過程,或者選擇要求使用者互動才能進行更新。
除了常規資源外,編譯器還需要發出一個“更新”以允許從舊版本更新到新版本。“更新”由兩部分組成
manifest 包含新的編譯雜湊和所有更新的 chunk 列表。每個 chunk 都包含所有更新模組的新程式碼(或表示模組已移除的標誌)。
編譯器確保這些構建之間模組 ID 和 chunk ID 的一致性。它通常將這些 ID 儲存在記憶體中(例如使用 webpack-dev-server),但也可以將其儲存在 JSON 檔案中。
HMR 是一個可選功能,僅影響包含 HMR 程式碼的模組。一個例子是透過 style-loader 打補丁樣式。為了使補丁生效,style-loader 實現了 HMR 介面;當它透過 HMR 接收到更新時,它會將舊樣式替換為新樣式。
類似地,在模組中實現 HMR 介面時,你可以描述模組更新時應發生的情況。然而,在大多數情況下,不必在每個模組中編寫 HMR 程式碼。如果一個模組沒有 HMR 處理器,更新會向上冒泡。這意味著單個處理器可以更新完整的模組樹。如果樹中的單個模組更新,則整個依賴項集合會被重新載入。
有關 module.hot 介面的詳細資訊,請參閱HMR API 頁面。
這裡事情變得有點技術性... 如果你對內部細節不感興趣,可以直接跳到HMR API 頁面或HMR 指南。
對於模組系統執行時,會發出額外的程式碼來跟蹤模組的 父級 和 子級。在管理方面,執行時支援兩種方法:check 和 apply。
check 方法向更新 manifest 發出 HTTP 請求。如果此請求失敗,則沒有可用更新。如果成功,則會將更新的 chunk 列表與當前載入的 chunk 列表進行比較。對於每個已載入的 chunk,都會下載相應的更新 chunk。所有模組更新都儲存在執行時中。當所有更新 chunk 都已下載並準備好應用時,執行時會切換到 ready 狀態。
apply 方法將所有更新的模組標記為無效。對於每個無效模組,模組本身或其父級中需要有一個更新處理器。否則,無效標誌會向上冒泡並同樣使父級無效。每次冒泡都會繼續,直到達到應用程式的入口點或具有更新處理器的模組(以先達到者為準)。如果它從入口點冒泡,則該過程失敗。
之後,所有無效模組被處理(透過 dispose 處理器)並解除安裝。然後更新當前雜湊,並呼叫所有 accept 處理器。執行時切換回 空閒 狀態,一切恢復正常。
HMR 可以在開發中用作 LiveReload 的替代品。webpack-dev-server 支援熱模式,在此模式下,它會嘗試使用 HMR 進行更新,然後再嘗試重新載入整個頁面。有關詳細資訊,請參閱模組熱替換指南。