寒假赋闲在家,没啥业余爱好,闲暇之余喜欢学学好看的css效果
,然每次更改完样式都需要刷新浏览器,于是去寻热加载工具,未果,自己写了一个?
当然,您也可以用react
提供的cra
等类似工具实现此需求,但是我因为就想用简单一点的方式编辑css效果
,所以不喜勿喷哈
下文的网页热加载均指此需求
思路
网页热加载大概分为一下步骤
-
开启一个端口实现http服务
-
server监听文件夹
-
文件夹有变动的时候通过
SSE
发送给client -
client刷新重新获取页面
所以我们要用到的工具有
- Node包:
http
,fs
- WebAPIs:
localtion.reload()
,EventSource
开始
提供http
服务
首先,我们开启一个端口来提供http服务
const http = require('http');
const server = http.createServer((req, res) => {
});
server.listen(8080, () => {
console.log(`server running on http://localhost:8080/?...`)
});
node运行一下,这个时候服务已经开启啦http://localhost:8080/
接下来要提供静态资源的访问服务,这样我们才能看到我们的网页呀
这里我们使用fs.readFile
读取文件并响应http请求
注意⚠⚠更换自己的静态资源文件夹路径
const fs = require('fs');
//别忘了改成自己监听的文件夹
fs.readFile("/Users/shwei/code/livereload/public" + url, (err, data) => {
if (err) {
res.writeHead(404);
res.end("File Not Found");
return;
}
res.writeHead(200);
res.end(data);
});
加到我们的http服务
中就是这样
这里我们默认访问根目录返回index.html
,用一个函数封装一下给其他静态资源复用
const http = require("http");
const fs = require("fs");
const getStaticResource = (url, res) => {
fs.readFile("/Users/shwei/code/livereload/public" + url, (err, data) => {
if (err) {
res.writeHead(404);
res.end("File Not Found");
return;
}
res.writeHead(200);
res.end(data);
});
};
const server = http.createServer((req, res) => {
const { headers, url, method } = req;
if (url.toLowerCase() === "/" && method.toLowerCase() === "get") {
getStaticResource("/index.html", res);
return;
}
if (method.toLowerCase() === "get") getStaticResource(url, res);
});
server.listen(8080, () => {
console.log(`server running on http://localhost:8080/?...`);
});
这样的话,我们在相应的文件夹下建立index.html
就能在http://localhost:8080/
看到我们的网页啦
使用SSE
和文件监控实现热加载
接下来就是实现热加载啦
首先我们的网页中一定要默认链接一个JS文件
,里面放入我们SSE
需要的浏览器端API
//sse.js
const events = new EventSource("/events"); //监听我们http服务中的/events路由
events.onmessage = (event) => {
location.reload();
};
设定好监听的路由,只需要设置收到信息的时候刷新页面就好啦
不要忘记链接到HTML中
<script src="sse.js"></script>
接下来实现我们server端
的服务
首先是文件监听APIfs.watch
,我们要配合这个来给浏览器端发送消息
老样子,写一个函数包装一下,并且应该是立即执行的(因为我们想打开端口就用,如果有业务逻辑则不要学我)
(function watchFile() {
fs.watch("./public", { encoding: "buffer" }, () => {
client.writeHead(200, {
"Content-Type": "text/event-stream",
"Connection": "keep-alive",
"Cache-Control": "no-cache"
});//headers标准
client.end("data: reflush\n\n");//别忘了data:和\n\n
});
})();
你可能发现,我这里多了一个client
变量,不过别急我待会解释,要注意SSE
的通信标准(代码中注释)
由于SSE
的本质是不断向server
端发送GET
请求保持连接一直未中断
而我们只需要文件更改的时候发送信息给浏览器端,所以我这样安排了响应
if (url.toLowerCase() === "/events" && method.toLowerCase() === "get") {
client = res;
return;
}
每次响应我们只需要保存“指针”,以便于文件更改的时候能找到
其实这里全局变量有些不优雅,但是别计较太多
到这里我们的功能已经实现完全啦
全代码
const http = require("http");
const fs = require("fs");
let client;
const server = http.createServer((req, res) => {
const { headers, url, method } = req;
if (url.toLowerCase() === "/" && method.toLowerCase() === "get") {
getStaticResource("/index.html", res);
return;
}
if (url.toLowerCase() === "/events" && method.toLowerCase() === "get") {
client = res;
return;
}
if (method.toLowerCase() === "get") getStaticResource(url, res);
});
server.listen(8080, () => {
console.log(`server running on http://localhost:8080/?...`);
});
(function watchFile() {
fs.watch("./public", { encoding: "buffer" }, () => {
client.writeHead(200, {
"Content-Type": "text/event-stream",
"Connection": "keep-alive",
"Cache-Control": "no-cache"
});//headers标准
client.end("data: reflush\n\n");//别忘了data和/n/n
});
})();
const getStaticResource = (url, res) => {
fs.readFile("/Users/shwei/code/livereload/public" + url, (err, data) => {
if (err) {
res.writeHead(404);
res.end("File Not Found");
return;
}
res.writeHead(200);
res.end(data);
});
};
打开你的代码编辑器和http://localhost:8080/
尽情享受吧!
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!