模塊熱替換(hot module replacement)
模塊熱替換(HMR - Hot Module Replacement)功能會在應用程序運行過程中替換纠屋、添加或刪除模塊袍辞,而無需重新加載整個頁面。主要是通過以下幾種方式失受,來顯著加快開發(fā)速度:
保留在完全重新加載頁面時丟失的應用程序狀態(tài)。
只更新變更內(nèi)容,以節(jié)省寶貴的開發(fā)時間差购。
調(diào)整樣式更加快速 - 幾乎相當于在瀏覽器調(diào)試器中更改樣式穷躁。
在應用程序中
通過以下步驟耕肩,可以做到在應用程序中置換(swap in and out)模塊:
應用程序代碼要求 HMR runtime 檢查更新。
HMR runtime(異步)下載更新问潭,然后通知應用程序代碼猿诸。
應用程序代碼要求 HMR runtime 應用更新。
HMR runtime(同步)應用更新睦授。
你可以設(shè)置 HMR两芳,以使此進程自動觸發(fā)更新,或者你可以選擇要求在用戶交互時進行更新去枷。
在編譯器中
除了普通資源怖辆,編譯器(compiler)需要發(fā)出 "update",以允許更新之前的版本到新的版本删顶。"update" 由兩部分組成:
更新后的 manifest(JSON)
一個或多個更新后的 chunk (JavaScript)
manifest 包括新的編譯 hash 和所有的待更新 chunk 目錄竖螃。每個更新 chunk 都含有對應于此 chunk 的全部更新模塊(或一個 flag 用于表明此模塊要被移除)的代碼。
編譯器確保模塊 ID 和 chunk ID 在這些構(gòu)建之間保持一致逗余。通常將這些 ID 存儲在內(nèi)存中(例如特咆,使用 webpack-dev-server 時),但是也可能將它們存儲在一個 JSON 文件中。
在模塊中
HMR 是可選功能腻格,只會影響包含 HMR 代碼的模塊画拾。舉個例子,通過 style-loader 為 style 樣式追加補丁菜职。為了運行追加補丁青抛,style-loader 實現(xiàn)了 HMR 接口;當它通過 HMR 接收到更新酬核,它會使用新的樣式替換舊的樣式蜜另。
類似的,當在一個模塊中實現(xiàn)了 HMR 接口嫡意,你可以描述出當模塊被更新后發(fā)生了什么举瑰。然而在多數(shù)情況下,不需要強制在每個模塊中寫入 HMR 代碼蔬螟。如果一個模塊沒有 HMR 處理函數(shù)此迅,更新就會冒泡(bubble up)。這意味著一個簡單的處理函數(shù)能夠?qū)φ麄€模塊樹(complete module tree)進行更新促煮。如果在這個模塊樹中邮屁,一個單獨的模塊被更新,那么整組依賴模塊都會被重新加載菠齿。
有關(guān) module.hot 接口的詳細信息佑吝,請查看 HMR API 頁面。
在 HMR Runtime 中
這些事情比較有技術(shù)性……如果你對其內(nèi)部不感興趣绳匀,可以隨時跳到 HMR API 頁面或 HMR 指南芋忿。
對于模塊系統(tǒng)的 runtime,附加的代碼被發(fā)送到 parents 和 children 跟蹤模塊疾棵。在管理方面戈钢,runtime 支持兩個方法 check 和 apply。
check 發(fā)送 HTTP 請求來更新 manifest是尔。如果請求失敗殉了,說明沒有可用更新。如果請求成功拟枚,待更新 chunk 會和當前加載過的 chunk 進行比較薪铜。對每個加載過的 chunk,會下載相對應的待更新 chunk恩溅。當所有待更新 chunk 完成下載隔箍,就會準備切換到 ready 狀態(tài)。
apply 方法將所有被更新模塊標記為無效脚乡。對于每個無效模塊蜒滩,都需要在模塊中有一個更新處理函數(shù)(update handler),或者在它的父級模塊們中有更新處理函數(shù)。否則俯艰,無效標記冒泡捡遍,并也使父級無效。每個冒泡繼續(xù)蟆炊,直到到達應用程序入口起點稽莉,或者到達帶有更新處理函數(shù)的模塊(以最先到達為準,冒泡停止)涩搓。如果它從入口起點開始冒泡,則此過程失敗劈猪。
之后昧甘,所有無效模塊都被(通過 dispose 處理函數(shù))處理和解除加載。然后更新當前 hash战得,并且調(diào)用所有 "accept" 處理函數(shù)充边。runtime 切換回閑置狀態(tài)(idle state),一切照常繼續(xù)常侦。
入門
在開發(fā)過程中浇冰,可以將 HMR 作為 LiveReload 的替代。webpack-dev-server 支持 hot 模式聋亡,在試圖重新加載整個頁面之前肘习,熱模式會嘗試使用 HMR 來更新。更多細節(jié)請查看模塊熱更新指南坡倔。
與許多其他功能一樣漂佩,webpack 的強大之處在于它的可定制化。取決于特定項目需求罪塔,會有許多種配置 HMR 的方式投蝉。然而,對于多數(shù)實現(xiàn)來說征堪,webpack-dev-server 能夠配合良好瘩缆,可以讓你快速入門 HMR。