Angular開發實踐(二):HRM運行機制

引言

angular-start項目中啓用了模塊熱替換(HMR - Hot Module Replacement)功能,關於如何在angular-cli啓用HRM,請查看HRM配置css

HMR是個什麼東西呢?webpack

HMRwebpack提供的一個功能,angular-cli使用了它,它會在應用程序運行過程當中替換、添加或刪除模塊,而無需從新加載整個頁面。主要是經過如下幾種方式,來顯著加快開發速度:git

  • 保留在徹底從新加載頁面時丟失的應用程序狀態github

  • 只更新變動內容,以節省寶貴的開發時間web

  • 調整樣式更加快速 - 幾乎至關於在瀏覽器調試器中更改樣式api

這一切是如何運行的?

咱們先看看具體的效果:瀏覽器

一、啓動angular-start項目,在控制檯你能夠看到HRM已經啓用的消息:app

image

二、而後經過瀏覽器控制檯能夠看到,第一次加載請求了全部的資源:異步

image

三、此時,修改一處代碼保存,瀏覽器並未刷新就自動顯示修改以後的效果,再看瀏覽器控制檯只請求了新修改的js:webpack-dev-server

image

下面讓咱們從一些不一樣的角度觀察,以瞭解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用於代表此模塊要被移除)的代碼。

編譯器確保模塊IDchunk ID在這些構建之間保持一致。一般將這些ID存儲在內存中(例如,使用webpack-dev-server時),可是也可能將它們存儲在一個JSON文件中。

在模塊中

HMR是可選功能,只會影響包含HMR代碼的模塊。舉個例子,經過style-loaderstyle樣式追加補丁。爲了運行追加補丁,style-loader實現了HMR接口;當它經過HMR接收到更新,它會使用新的樣式替換舊的樣式。

相似的,當在一個模塊中實現了HMR接口,你能夠描述出當模塊被更新後發生了什麼。然而在多數狀況下,不須要強制在每一個模塊中寫入HMR代碼。若是一個模塊沒HMR處理函數,更新就會冒泡。這意味着一個簡單的處理函數可以對整個模塊樹(complete module tree)進行更新。若是在這個模塊樹中,一個單獨的模塊被更新,那麼整組依賴模塊都會被從新加載。

有關 module.hot 接口的詳細信息,請查看HMR API頁面

在HMR Runtime中

對於模塊系統的runtime,附加的代碼被髮送到parentschildren跟蹤模塊。在管理方面,runtime支持兩個方法checkapply

check發送HTTP請求來更新manifest。若是請求失敗,說明沒有可用更新。若是請求成功,待更新chunk會和當前加載過的chunk進行比較。對每一個加載過的chunk,會下載相對應的待更新chunk。當全部待更新chunk完成下載,就會準備切換到ready狀態。

apply方法將全部被更新模塊標記爲無效。對於每一個無效模塊,都須要在模塊中有一個更新處理函數,或者在它的父級模塊們中有更新處理函數。不然,無效標記冒泡,並也使父級無效。每一個冒泡繼續直到到達應用程序入口起點,或者到達帶有更新處理函數的模塊(以最早到達爲準)。若是它從入口起點開始冒泡,則此過程失敗。

以後,全部無效模塊都被(經過dispose處理函數)處理和解除加載。而後更新當前hash,而且調用全部accept處理函數。runtime切換回閒置狀態,一切照常繼續。

參考文章

http://www.css88.com/doc/webp...

相關文章
相關標籤/搜索