引言
在angular-start項目中啟用了模塊熱替換(HMR - Hot Module Replacement)
功能,關于如何在angular-cli
啟用HRM
,請查看HRM配置
那HMR
是個什么東西呢?
HMR
是webpack
提供的一個功能,angular-cli
使用了它,它會在應用程序運行過程中替換、添加或刪除模塊,而無需重新加載整個頁面。主要是通過以下幾種方式,來顯著加快開發速度:
- 保留在完全重新加載頁面時丟失的應用程序狀態
- 只更新變更內容,以節省寶貴的開發時間
- 調整樣式更加快速 - 幾乎相當于在瀏覽器調試器中更改樣式
這一切是如何運行的?
我們先看看具體的效果:
1、啟動angular-start
項目,在控制臺你可以看到HRM
已經啟用的消息:
2、然后通過瀏覽器控制臺可以看到,第一次加載請求了所有的資源:
3、此時,修改一處代碼保存,瀏覽器并未刷新就自動顯示修改之后的效果,再看瀏覽器控制臺只請求了新修改的js:
下面讓我們從一些不同的角度觀察,以了解HMR
的工作原理……
在應用程序中
通過以下步驟,可以做到在應用程序中置換(swap in and out
)模塊:
- 應用程序代碼要求 HMR runtime 檢查更新
- HMR runtime(異步)下載更新,然后通知應用程序代碼
- 應用程序代碼要求 HMR runtime 應用更新
- HMR runtime(異步)應用更新
在編譯器中
除了普通資源,編譯器(compiler
)需要發出update
,以允許更新之前的版本到新的版本。update
由兩部分組成:
- 更新后的
manifest (JSON)
- 一個或多個更新后的
chunk (JavaScript)
manifest
包括新的編譯hash
和所有的待更新chunk
目錄。每個更新chunk
都含有對應于此chunk
的全部更新模塊(或一個flag
用于表明此模塊要被移除)的代碼。
編譯器確保模塊ID
和chunk ID
在這些構建之間保持一致。通常將這些ID
存儲在內存中(例如,使用webpack-dev-server
時),但是也可能將它們存儲在一個JSON
文件中。
在模塊中
HMR
是可選功能,只會影響包含HMR
代碼的模塊。舉個例子,通過style-loader
為style
樣式追加補丁。為了運行追加補丁,style-loader
實現了HMR
接口;當它通過HMR
接收到更新,它會使用新的樣式替換舊的樣式。
類似的,當在一個模塊中實現了HMR
接口,你可以描述出當模塊被更新后發生了什么。然而在多數情況下,不需要強制在每個模塊中寫入HMR
代碼。如果一個模塊沒HMR
處理函數,更新就會冒泡。這意味著一個簡單的處理函數能夠對整個模塊樹(complete module tree)
進行更新。如果在這個模塊樹中,一個單獨的模塊被更新,那么整組依賴模塊都會被重新加載。
有關 module.hot 接口的詳細信息,請查看HMR API頁面。
在HMR Runtime中
對于模塊系統的runtime
,附加的代碼被發送到parents
和children
跟蹤模塊。在管理方面,runtime
支持兩個方法check
和apply
。
check
發送HTTP
請求來更新manifest
。如果請求失敗,說明沒有可用更新。如果請求成功,待更新chunk
會和當前加載過的chunk
進行比較。對每個加載過的chunk
,會下載相對應的待更新chunk
。當所有待更新chunk
完成下載,就會準備切換到ready
狀態。
apply
方法將所有被更新模塊標記為無效。對于每個無效模塊,都需要在模塊中有一個更新處理函數,或者在它的父級模塊們中有更新處理函數。否則,無效標記冒泡,并也使父級無效。每個冒泡繼續直到到達應用程序入口起點,或者到達帶有更新處理函數的模塊(以最先到達為準)。如果它從入口起點開始冒泡,則此過程失敗。
之后,所有無效模塊都被(通過dispose
處理函數)處理和解除加載。然后更新當前hash
,并且調用所有accept
處理函數。runtime
切換回閑置狀態,一切照常繼續。
文章列表