Webpack & The Hot Module Replacement熱模塊替換原理解析


Webpack & The Hot Module Replacement熱模塊替換原理解析

The Hot Module Replacement(HMR)俗稱熱模塊替換。主要用來當代碼產生變化后,可以在不刷新游覽器的情況下對局部代碼塊進行替換更新。這在很多情況下都很有用,例如在處理彈出框時,使用HMR可以及時的看到變化,如果用刷新游覽器的方式會回到初始頁面。

很多人使用過HMR卻不知道它是如何工作的,這里會對HMR實現原理進行解析。

關於HMR需要知道的一些事

  • HMR是Webpack的一個可選功能,如果想使用需要主動打開。

  • 需要通過webpack-dev-server方式來管理webpack(另一種方式是CLI)

  • HMR只能工作在實現了HMR API的loaders里,例如:‘style-loader’,'react-hot-loader'

  • HMR只能在開發環境中使用,因為HMR會在打包的js中添加了很多額外的代碼,並且webpack-dev-server也只用於開發環境。

HMR工作原理

webpack會在打包的js中注入很多js庫來讓HMR工作,下圖展示了當一個文件發生變化是HMR是如何工作的。

圖片顏色說明:

紫色:發生改變的js或者css文件

橘色:發生變化的代碼塊說明,變化后的代碼塊內容

彩蘭色:項目代碼

綠色:webpack-dev-server相關的庫,有圖中可以發現,webpack-dev-server主要負責server端和游覽器端的通信。

藍色:webpack核心和插件庫,由圖中可以發現,server端代碼的監聽以及游覽器端新代碼的替換都是由webpack的不同模塊處理。

紅色:react-loader或者style-loader等HMR庫

 

執行流程:

  1. 當監聽到文件發生變化時,webpack 使用HotModuleReplacementPlugin生成一個mainifest(一個json結構描述了發生變化的modules列表)和update file(一個js文件包含修改后的代碼內容)

  2. webpack將上述變化信息告訴webpack-dev-server

  3. webpack-dev-server通過webSocket給運行在游覽器上的‘webpack-dev-server/client’(在打包時注入的js代碼)發送一條‘invalide’信息以及更新后代碼的hash值(該hash值本次不會用到,使用上一版本的hash值).

  4. ’webpack-dev-server/client’會將上一版本代碼的hash傳遞給“hot/dev-server”

  5. ‘hot/dev-server’使用JsonpRuntime向server端發送帶有上版本hash的ajax請求,server端返回一個json,該json包含要所有要更新的模塊的hash值。

  6. JsonpRuntime根據返回的json值使用jsonp請求具體的代碼塊,jsonp返回的js代碼類似下面:

webpackHotUpdate(0,
{
82:
 function(module, exports, __webpack_require__) {
   exports = module.exports = __webpack_require__(79)();
   exports.push([module.id, “input {\n background: pink;\n}”, “”])
}
})
  1. 代碼會調用webpackHotUpdate方法並攜帶module_id和具體修改內容。

  2. HMR runtime本身並不會處理代碼修改,它會將不同文件交給對應的loader runtime處理(例如:react-hot-loader runtime 或者 style-loader runtime)

  3. 如果更新失敗,會回退刷新游覽器獲取最新代碼。

 

示例

當游覽器首次加載app時,server端會推送當前代碼版本號current_hash。

 

當修改style文件后,server端HotModuleReplacementPlugin會根據更新內容生成manifest和js文件,文件名根據current_hash生成,然后更新current_hash,並將新的hash值推送給游覽器端,用作下次更新。

游覽器端webpack-dev-server/client接收到新的hash值后,會將previous hash值傳遞給webpack/hot/dev-server,dev-server根據previous hash請求具體的mainifest和js代碼,並使用jsonp更新。

 

參考文檔:

Webpack & The Hot Module Replacement

Webpack HMR原理解析


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM