說說webpack的熱更新是如何做到的?原理是什麼?

来源:https://www.cnblogs.com/smileZAZ/p/18211562
-Advertisement-
Play Games

一、是什麼 HMR全稱 Hot Module Replacement,可以理解為模塊熱替換,指在應用程式運行過程中,替換、添加、刪除模塊,而無需重新刷新整個應用 例如,我們在應用運行過程中修改了某個模塊,通過自動刷新會導致整個應用的整體刷新,那頁面中的狀態信息都會丟失 如果使用的是 HMR,就可以實 ...


一、是什麼

HMR全稱 Hot Module Replacement,可以理解為模塊熱替換,指在應用程式運行過程中,替換、添加、刪除模塊,而無需重新刷新整個應用

例如,我們在應用運行過程中修改了某個模塊,通過自動刷新會導致整個應用的整體刷新,那頁面中的狀態信息都會丟失

如果使用的是 HMR,就可以實現只將修改的模塊實時替換至應用中,不必完全刷新整個應用

webpack中配置開啟熱模塊也非常的簡單,如下代碼:

const webpack = require('webpack')
module.exports = {
  // ...
  devServer: {
    // 開啟 HMR 特性
    hot: true
    // hotOnly: true
  }
}

通過上述這種配置,如果我們修改並保存css文件,確實能夠以不刷新的形式更新到頁面中

但是,當我們修改並保存js文件之後,頁面依舊自動刷新了,這裡並沒有觸發熱模塊

所以,HMR並不像 Webpack 的其他特性一樣可以開箱即用,需要有一些額外的操作

我們需要去指定哪些模塊發生更新時進行HRM,如下代碼:

if(module.hot){
    module.hot.accept('./util.js',()=>{
        console.log("util.js更新了")
    })
}

二、實現原理

首先來看看一張圖,如下:

  • Webpack Compile:將 JS 源代碼編譯成 bundle.js
  • HMR Server:用來將熱更新的文件輸出給 HMR Runtime
  • Bundle Server:靜態資源文件伺服器,提供文件訪問路徑
  • HMR Runtime:socket伺服器,會被註入到瀏覽器,更新文件的變化
  • bundle.js:構建輸出的文件
  • 在HMR Runtime 和 HMR Server之間建立 websocket,即圖上4號線,用於實時更新文件變化

上面圖中,可以分成兩個階段:

  • 啟動階段為上圖 1 - 2 - A - B

在編寫未經過webpack打包的源代碼後,Webpack Compile 將源代碼和 HMR Runtime 一起編譯成 bundle文件,傳輸給Bundle Server 靜態資源伺服器

  • 更新階段為上圖 1 - 2 - 3 - 4

當某一個文件或者模塊發生變化時,webpack監聽到文件變化對文件重新編譯打包,編譯生成唯一的hash值,這個hash值用來作為下一次熱更新的標識

根據變化的內容生成兩個補丁文件:manifest(包含了 hash 和 chundId,用來說明變化的內容)和chunk.js 模塊

由於socket伺服器在HMR Runtime 和 HMR Server之間建立 websocket鏈接,當文件發生改動的時候,服務端會向瀏覽器推送一條消息,消息包含文件改動後生成的hash值,如下圖的h屬性,作為下一次熱更細的標識

 

在瀏覽器接受到這條消息之前,瀏覽器已經在上一次socket 消息中已經記住了此時的hash 標識,這時候我們會創建一個 ajax 去服務端請求獲取到變化內容的 manifest 文件

mainfest文件包含重新build生成的hash值,以及變化的模塊,對應上圖的c屬性

瀏覽器根據 manifest 文件獲取模塊變化的內容,從而觸發render流程,實現局部模塊更新

三、總結

關於webpack熱模塊更新的總結如下:

  • 通過webpack-dev-server創建兩個伺服器:提供靜態資源的服務(express)和Socket服務
  • express server 負責直接提供靜態資源的服務(打包後的資源直接被瀏覽器請求和解析)
  • socket server 是一個 websocket 的長連接,雙方可以通信
  • 當 socket server 監聽到對應的模塊發生變化時,會生成兩個文件.json(manifest文件)和.js文件(update chunk)
  • 通過長連接,socket server 可以直接將這兩個文件主動發送給客戶端(瀏覽器)
  • 瀏覽器拿到兩個新的文件後,通過HMR runtime機制,載入這兩個文件,並且針對修改的模塊進行更新

參考文獻

  • https://zhuanlan.zhihu.com/p/138446061
  • https://github.com/Jocs/jocs.github.io/issues/15
  • https://juejin.cn/post/6844904134697549832
  • https://vue3js.cn/interview/

如果對您有所幫助,歡迎您點個關註,我會定時更新技術文檔,大家一起討論學習,一起進步。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 事情是這樣的,因為系統漏洞問題,需要升級openssh,從OpenSSH_9.3p1升級到OpenSSH_9.3p2 系統版本:CentOS 7 升級OpenSSH_9.3p2之前需要先升級zlib 從官網下載 wget https://www.zlib.net/zlib-1.3.1.tar.gz ...
  • Linux不像windows系統那樣方便的圖形界面,特別是作為伺服器使用的時候,只有命令行可以使用。 我有個雲伺服器平時用來做一些數據分享用的,最近想看看磁碟和其中文件的占用情況,於是搜索並學習了一些查看磁碟空間信息的命令,命令雖然簡單,但對我自己來說還是有些新的東西值得記錄。 1. df 首先,登 ...
  • Centos7安裝weblogic 1、配置java環境weblogic運行依賴java環境,所以第一步先配置java環境上傳、解壓jdk安裝包[root@bogon ~]# rz -be[root@bogon ~]# tar -zxvf jdk1.8.tar.gz 配置java環境變數[root@ ...
  • 背景 根據orangepi zero2用戶手冊說明,linux5.13內核不能使用 modprobe fbtft_device 驅動spi lcd 查看linux內核源碼提交記錄,發現在v5.4-rc3中刪除了fbtft_device.c文件 commit如下 staging/fbtft: Remo ...
  • 一、卸載mariadb的rpm包 1、首先,你需要找出已安裝的MariaDB包的具體名稱。可以使用以下命令列出所有已安裝的MariaDB包: rpm -qa | grep mariadb 2、刪除命令(安裝mysql不一定需要卸載)yum -y remove +【上圖的文件名】或者rpm -e -- ...
  • 前言 應用中的信息傳遞是為了實現各種功能和交互。信息傳遞可以幫助用戶和應用之間進行有效的溝通和交流。通過信息傳遞,應用可以向用戶傳遞重要的消息、通知和提示,以提供及時的反饋和指導。同時,用戶也可以通過信息傳遞嚮應用發送指令、請求和反饋,以實現個性化的需求和操作。 信息傳遞還可以幫助應用之間實現數 ...
  • Symbol 引用 iconfont icon圖標庫 Symbol 引用 這是一種全新的使用方式,應該說這才是未來的主流,也是平臺目前推薦的用法。相關介紹可以參考這篇文章 這種用法其實是做了一個 SVG 的集合,與另外兩種相比具有如下特點: 支持多色圖標了,不再受單色限制。 通過一些技巧,支持像字體 ...
  • XML中的字元串數據類型表示字元序列,包括換行、回車和製表符。處理器不修改值。`normalizedString`去除這些特殊字元,`token`則進一步移除前導和尾隨空格及多餘空格。字元串類型可使用枚舉、長度等限制。`date`和`dateTime`數據類型表示日期和時間,`duration`表示... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...