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

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

The Hot Module Replacement(HMR)俗稱熱模塊替換。主要用來當代碼產生變化後,能夠在不刷新遊覽器的狀況下對局部代碼塊進行替換更新。這在不少狀況下都頗有用,例如在處理彈出框時,使用HMR能夠及時的看到變化,若是用刷新遊覽器的方式會回到初始頁面。css

不少人使用過HMR殊不知道它是如何工做的,這裏會對HMR實現原理進行解析。html

關於HMR須要知道的一些事

  • HMR是Webpack的一個可選功能,若是想使用須要主動打開。react

  • 須要經過webpack-dev-server方式來管理webpack(另外一種方式是CLI)webpack

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

  • HMR只能在開發環境中使用,由於HMR會在打包的js中添加了不少額外的代碼,而且webpack-dev-server也只用於開發環境。ajax

HMR工做原理

webpack會在打包的js中注入不少js庫來讓HMR工做,下圖展現了當一個文件發生變化是HMR是如何工做的。json

圖片顏色說明:app

紫色:發生改變的js或者css文件webpack-dev-server

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

彩蘭色:項目代碼

綠色: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原理解析

原文出處:https://www.cnblogs.com/chenkeyu/p/10801197.html

相關文章
相關標籤/搜索