注册

实现一个简易的热🥵🥵更新

简单模拟一个热更新


什么是热更新



热更新是指在应用程序运行时,对程序的部分内容进行更新,而无需重启整个应用程序。通常,热更新是在不停止整个应用程序的情况下,将新的代码、资源或配置应用于正在运行的应用程序,以实现功能修复、性能优化或新增功能等目的。



热更新的优点


实时反馈,提高开发效率:热更新允许开发人员在进行代码更改后立即看到结果,无需重新编译和重启应用程序。这大大减少了开发、测试和调试代码所需的时间,提高了开发效率。


保持应用程序状态:通过热更新,应用程序的状态可以在代码更改时得以保留。这意味着开发人员不需要在每次更改后重新导航到特定页面或重现特定的应用程序状态,从而节省了时间和精力。


webpack 中的热更新



在Webpack中,热更新(Hot Module Replacement,HMR)是一种通过在应用程序运行时替换代码的技术,而无需重新加载整个页面或应用程序。它提供了一种高效的开发方式,可以在开发过程中快速看到代码更改的效果,而不中断应用程序的状态。



原理如下:


客户端连接到开发服务器:当启动Webpack开发服务器时,它会在浏览器中创建一个WebSocket连接。


打包和构建模块:在开发模式下,Webpack会监视源代码文件的变化,并在代码更改时重新打包和构建模块。这些模块构成了应用程序的各个部分。


将更新的模块发送到浏览器:一旦Webpack重新构建了模块,它会将更新的模块代码通过WebSocket发送到浏览器端。


浏览器接收并处理更新的模块:浏览器接收到来自Webpack的更新模块代码后,会根据模块的标识进行处理。它使用模块热替换运行时(Hot Module Replacement Runtime)来执行以下操作:(个人理解就像是 AJAX 局部刷新的过程,不对请指出)


(1)找到被替换的模块并卸载它。


(2)下载新的模块代码,并对其进行注入和执行。


(3)重新渲染或更新应用程序的相关部分。


保持应用程序状态:热更新通过在模块替换时保持应用程序状态来确保用户不会失去当前的状态。这意味着在代码更改后,开发人员可以继续与应用程序进行交互,而无需手动重新导航到特定页面或重现特定状态。


代码模拟



在同一个目录下创建 server.js 和 watcher.js



server.js

const http = require("http");
const server = http.createServer((req, res) => {
res.statusCode = 200;
// 设置字符编码为 UTF-8,若有中文也不乱码
res.setHeader("Content-Type", "text/plain; charset=utf-8");
res.end("offer get!!!");
});

server.listen(7777, () => {
console.log("服务已启动在 7777 端口");
process.send("started");
});

// 监听来自 watcher.js 的消息
process.on("message", (message) => {
if (message === "refresh") {
// 重新加载资源或执行其他刷新操作
console.log("重新加载资源");
}
});


(1)使用 http.createServer 方法创建一个 HTTP 服务器实例,该服务器将监听来自客户端的请求。


(2)启动服务,当服务器成功启动并开始监听指定端口时,回调函数将被调用。


(3)通过调用 process.send 方法,我们向父进程发送一条消息,消息内容为字符串 "started",表示服务器已经启动。


(4)使用 process.on 方法监听来自父进程的消息。当收到名为 "refresh" 的消息时,回调函数将被触发。


(5)在回调函数中,我们可以执行资源重新加载或其他刷新操作。一般是做页面的刷新操作。


server.js 创建了一个简单的 HTTP 服务器。当有请求到达时,服务器会返回 "offer get!!!" 的文本响应。它还与父进程进行通信,当收到名为 "refresh" 的消息时,会执行资源重新加载操作。


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("文件已经被修改,重新加载");

// 如果之前的子进程存在,终止该子进程
childProcess && childProcess.kill();

// 创建新的子进程
childProcess = fork(filePath);
childProcess.on("message", callback);
}
});
};

const startServer = (filePath) => {
// 创建一个子进程,启动服务器
childProcess = fork(filePath);
childProcess.on("message", () => {
console.log("服务已启动!");
// 监听文件变化
watchFile(filePath, () => {
console.log("文件已被修改");
});
});
};

// 注意文件的相对位置
startServer("./server.js");


watcher.js 是一个用于监视文件变化并自动重新启动服务器的脚本。


(1)首先,引入 fs 模块和 child_processfork 方法,fork 方法是 Node.js 中 child_process 模块提供的一个函数,用于创建一个新的子进程,通过调用 fork 方法,可以在主进程中创建一个全新的子进程,该子进程可以独立地执行某个脚本文件。


(2)watchFile 函数用于监视指定文件的变化。当文件发生变化时,会触发回调函数。


(3)startServer 函数负责启动服务器。它会创建一个子进程,并以指定的文件作为脚本运行。子进程将监听来自 server.js 的消息。


(4)在 startServer 函数中,首先创建了一个子进程来启动服务器并发送一个消息表示服务器已启动。


(5)然后,通过调用 watchFile 函数,开始监听指定的文件变化。当文件发生变化时,会触发回调函数。


(6)回调函数中,会终止之前的子进程(如果存在),然后创建一个新的子进程,重新运行 server.js


watcher.js 负责监视特定文件的变化,并在文件发生变化时自动重新启动服务器。它使用 child_process 模块创建子进程来运行 server.js,并在需要重新启动服务器时终止旧的子进程并创建新的子进程。这样就可以实现服务器的热更新,当代码发生变化时,无需手动重启服务器,watcher.js 将自动处理这个过程。


效果图


打开本地的 7777 端口,看到了 'offet get!!!' 的初始字样


d95de2deebc737edd45c68ccded1f672.png


当修改了响应文字时,刷新页面,无需重启服务,也能看到更新的字样!

c29c5e56ff4ac9c962f0f0f1e019c865.png
作者:PINKinee
链接:https://juejin.cn/post/7269316739796058169
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0 个评论

要回复文章请先登录注册