引言 在 "angular start" 項目中啟用了 功能,關於如何在 啟用 ,請查看 "HRM配置" 那 是個什麼東西呢? 是`webpack angular cli`使用了它,它會在應用程式運行過程中替換、添加或刪除模塊,而無需重新載入整個頁面。主要是通過以下幾種方式,來顯著加快開發速度: 保 ...
引言
在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
切換回閑置狀態,一切照常繼續。