在angular-start項目中啓用了模塊熱替換(HMR - Hot Module Replacement)
功能,關於如何在angular-cli
啓用HRM
,請查看HRM配置css
那HMR
是個什麼東西呢?webpack
HMR
是webpack
提供的一個功能,angular-cli
使用了它,它會在應用程序運行過程當中替換、添加或刪除模塊,而無需從新加載整個頁面。主要是經過如下幾種方式,來顯著加快開發速度:git
保留在徹底從新加載頁面時丟失的應用程序狀態github
只更新變動內容,以節省寶貴的開發時間web
調整樣式更加快速 - 幾乎至關於在瀏覽器調試器中更改樣式api
咱們先看看具體的效果:瀏覽器
一、啓動angular-start
項目,在控制檯你能夠看到HRM
已經啓用的消息:app
二、而後經過瀏覽器控制檯能夠看到,第一次加載請求了全部的資源:異步
三、此時,修改一處代碼保存,瀏覽器並未刷新就自動顯示修改以後的效果,再看瀏覽器控制檯只請求了新修改的js:webpack-dev-server
下面讓咱們從一些不一樣的角度觀察,以瞭解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頁面。
對於模塊系統的runtime
,附加的代碼被髮送到parents
和children
跟蹤模塊。在管理方面,runtime
支持兩個方法check
和apply
。
check
發送HTTP
請求來更新manifest
。若是請求失敗,說明沒有可用更新。若是請求成功,待更新chunk
會和當前加載過的chunk
進行比較。對每一個加載過的chunk
,會下載相對應的待更新chunk
。當全部待更新chunk
完成下載,就會準備切換到ready
狀態。
apply
方法將全部被更新模塊標記爲無效。對於每一個無效模塊,都須要在模塊中有一個更新處理函數,或者在它的父級模塊們中有更新處理函數。不然,無效標記冒泡,並也使父級無效。每一個冒泡繼續直到到達應用程序入口起點,或者到達帶有更新處理函數的模塊(以最早到達爲準)。若是它從入口起點開始冒泡,則此過程失敗。
以後,全部無效模塊都被(經過dispose
處理函數)處理和解除加載。而後更新當前hash
,而且調用全部accept
處理函數。runtime
切換回閒置狀態,一切照常繼續。