使用JavaScript實現(xiàn)一個簡易的熱更新
什么是熱更新
熱更新是指在應(yīng)用程序運行時,對程序的部分內(nèi)容進行更新,而無需重啟整個應(yīng)用程序。通常,熱更新是在不停止整個應(yīng)用程序的情況下,將新的代碼、資源或配置應(yīng)用于正在運行的應(yīng)用程序,以實現(xiàn)功能修復(fù)、性能優(yōu)化或新增功能等目的。
熱更新的優(yōu)點
實時反饋,提高開發(fā)效率:熱更新允許開發(fā)人員在進行代碼更改后立即看到結(jié)果,無需重新編譯和重啟應(yīng)用程序。這大大減少了開發(fā)、測試和調(diào)試代碼所需的時間,提高了開發(fā)效率。
保持應(yīng)用程序狀態(tài):通過熱更新,應(yīng)用程序的狀態(tài)可以在代碼更改時得以保留。這意味著開發(fā)人員不需要在每次更改后重新導(dǎo)航到特定頁面或重現(xiàn)特定的應(yīng)用程序狀態(tài),從而節(jié)省了時間和精力。
webpack 中的熱更新
在Webpack中,熱更新(Hot Module Replacement,HMR)是一種通過在應(yīng)用程序運行時替換代碼的技術(shù),而無需重新加載整個頁面或應(yīng)用程序。它提供了一種高效的開發(fā)方式,可以在開發(fā)過程中快速看到代碼更改的效果,而不中斷應(yīng)用程序的狀態(tài)。
原理如下:
客戶端連接到開發(fā)服務(wù)器:當(dāng)啟動Webpack開發(fā)服務(wù)器時,它會在瀏覽器中創(chuàng)建一個WebSocket連接。
打包和構(gòu)建模塊:在開發(fā)模式下,Webpack會監(jiān)視源代碼文件的變化,并在代碼更改時重新打包和構(gòu)建模塊。這些模塊構(gòu)成了應(yīng)用程序的各個部分。
將更新的模塊發(fā)送到瀏覽器:一旦Webpack重新構(gòu)建了模塊,它會將更新的模塊代碼通過WebSocket發(fā)送到瀏覽器端。
瀏覽器接收并處理更新的模塊:瀏覽器接收到來自Webpack的更新模塊代碼后,會根據(jù)模塊的標識進行處理。它使用模塊熱替換運行時(Hot Module Replacement Runtime)來執(zhí)行以下操作:(個人理解就像是 AJAX 局部刷新的過程,不對請指出)
(1)找到被替換的模塊并卸載它。
(2)下載新的模塊代碼,并對其進行注入和執(zhí)行。
(3)重新渲染或更新應(yīng)用程序的相關(guān)部分。
保持應(yīng)用程序狀態(tài):熱更新通過在模塊替換時保持應(yīng)用程序狀態(tài)來確保用戶不會失去當(dāng)前的狀態(tài)。這意味著在代碼更改后,開發(fā)人員可以繼續(xù)與應(yīng)用程序進行交互,而無需手動重新導(dǎo)航到特定頁面或重現(xiàn)特定狀態(tài)。
代碼模擬
在同一個目錄下創(chuàng)建 server.js 和 watcher.js
server.js
const http = require("http"); const server = http.createServer((req, res) => { res.statusCode = 200; // 設(shè)置字符編碼為 UTF-8,若有中文也不亂碼 res.setHeader("Content-Type", "text/plain; charset=utf-8"); res.end("offer get!!!"); }); server.listen(7777, () => { console.log("服務(wù)已啟動在 7777 端口"); process.send("started"); }); // 監(jiān)聽來自 watcher.js 的消息 process.on("message", (message) => { if (message === "refresh") { // 重新加載資源或執(zhí)行其他刷新操作 console.log("重新加載資源"); } });
(1)使用 http.createServer
方法創(chuàng)建一個 HTTP 服務(wù)器實例,該服務(wù)器將監(jiān)聽來自客戶端的請求。
(2)啟動服務(wù),當(dāng)服務(wù)器成功啟動并開始監(jiān)聽指定端口時,回調(diào)函數(shù)將被調(diào)用。
(3)通過調(diào)用 process.send
方法,我們向父進程發(fā)送一條消息,消息內(nèi)容為字符串 "started",表示服務(wù)器已經(jīng)啟動。
(4)使用 process.on
方法監(jiān)聽來自父進程的消息。當(dāng)收到名為 "refresh" 的消息時,回調(diào)函數(shù)將被觸發(fā)。
(5)在回調(diào)函數(shù)中,我們可以執(zhí)行資源重新加載或其他刷新操作。一般是做頁面的刷新操作。
server.js 創(chuàng)建了一個簡單的 HTTP 服務(wù)器。當(dāng)有請求到達時,服務(wù)器會返回 "offer get!!!" 的文本響應(yīng)。它還與父進程進行通信,當(dāng)收到名為 "refresh" 的消息時,會執(zhí)行資源重新加載操作。
watcher.js
const fs = require("fs"); const { fork } = require("child_process"); let childProcess = null; const watchFile = (filePath, callback) => { fs.watch(filePath, (event) => { if (event === "change") { console.log("文件已經(jīng)被修改,重新加載"); // 如果之前的子進程存在,終止該子進程 childProcess && childProcess.kill(); // 創(chuàng)建新的子進程 childProcess = fork(filePath); childProcess.on("message", callback); } }); }; const startServer = (filePath) => { // 創(chuàng)建一個子進程,啟動服務(wù)器 childProcess = fork(filePath); childProcess.on("message", () => { console.log("服務(wù)已啟動!"); // 監(jiān)聽文件變化 watchFile(filePath, () => { console.log("文件已被修改"); }); }); }; // 注意文件的相對位置 startServer("./server.js");
watcher.js
是一個用于監(jiān)視文件變化并自動重新啟動服務(wù)器的腳本。
(1)首先,引入 fs
模塊和 child_process
的 fork
方法,fork
方法是 Node.js 中 child_process
模塊提供的一個函數(shù),用于創(chuàng)建一個新的子進程,通過調(diào)用 fork
方法,可以在主進程中創(chuàng)建一個全新的子進程,該子進程可以獨立地執(zhí)行某個腳本文件。
(2)watchFile
函數(shù)用于監(jiān)視指定文件的變化。當(dāng)文件發(fā)生變化時,會觸發(fā)回調(diào)函數(shù)。
(3)startServer
函數(shù)負責(zé)啟動服務(wù)器。它會創(chuàng)建一個子進程,并以指定的文件作為腳本運行。子進程將監(jiān)聽來自 server.js
的消息。
(4)在 startServer
函數(shù)中,首先創(chuàng)建了一個子進程來啟動服務(wù)器并發(fā)送一個消息表示服務(wù)器已啟動。
(5)然后,通過調(diào)用 watchFile
函數(shù),開始監(jiān)聽指定的文件變化。當(dāng)文件發(fā)生變化時,會觸發(fā)回調(diào)函數(shù)。
(6)回調(diào)函數(shù)中,會終止之前的子進程(如果存在),然后創(chuàng)建一個新的子進程,重新運行 server.js
。
watcher.js
負責(zé)監(jiān)視特定文件的變化,并在文件發(fā)生變化時自動重新啟動服務(wù)器。它使用 child_process
模塊創(chuàng)建子進程來運行 server.js
,并在需要重新啟動服務(wù)器時終止舊的子進程并創(chuàng)建新的子進程。這樣就可以實現(xiàn)服務(wù)器的熱更新,當(dāng)代碼發(fā)生變化時,無需手動重啟服務(wù)器,watcher.js
將自動處理這個過程。
效果圖
打開本地的 7777 端口,看到了 'offet get!!!' 的初始字樣
當(dāng)修改了響應(yīng)文字時,刷新頁面,無需重啟服務(wù),也能看到更新的字樣!
到此這篇關(guān)于使用JavaScript實現(xiàn)一個簡易的熱更新的文章就介紹到這了,更多相關(guān)JavaScript熱更新內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解JavaScript的閉包、IIFE、apply、函數(shù)與對象
本文主要對JavaScript的閉包、IIFE、apply、函數(shù)與對象進行詳細介紹。有很好的參考價值,需要的朋友一起來看下吧2016-12-12javascript實現(xiàn)文字圖片上下滾動的具體實例
這篇文章介紹了在JS中文字圖片上下滾動的實現(xiàn)代碼,需要的朋友可以參考一下2013-06-06引入autocomplete組件時JS報未結(jié)束字符串常量錯誤
在引入jQuery的autocomplete組件時,遇到j(luò)s報未結(jié)束字符串常量錯誤,原因及解決方法如下,大家可以參考下2014-03-03js匿名函數(shù)的調(diào)用示例(形式多種多樣)
匿名函數(shù)就是沒有實際名字的函數(shù),javaScript的匿名函數(shù)形式多樣,下面就一一為大家羅列出來2014-08-08