文章出處

引言

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

HMR是個什么東西呢?

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

  • 保留在完全重新加載頁面時丟失的應用程序狀態
  • 只更新變更內容,以節省寶貴的開發時間
  • 調整樣式更加快速 - 幾乎相當于在瀏覽器調試器中更改樣式

這一切是如何運行的?

我們先看看具體的效果:

1、啟動angular-start項目,在控制臺你可以看到HRM已經啟用的消息:

image

2、然后通過瀏覽器控制臺可以看到,第一次加載請求了所有的資源:

image

3、此時,修改一處代碼保存,瀏覽器并未刷新就自動顯示修改之后的效果,再看瀏覽器控制臺只請求了新修改的js:

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切換回閑置狀態,一切照常繼續。


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()