如何让Node服务实现自动重启

「这是我参与2022首次更文挑战的第2天,活动详情查看:2022首次更文挑战」。

Dear,大家好,我是“前端小鑫同学”,😇长期从事前端开发,安卓开发,热衷技术,在编程路上越走越远~


当我们在做Node服务端开发的时候通常都会监听一个启动的端口来进行通信,当服务的内容发生改变的时候总是需要重新启动服务来保证服务内容可以被页面或接口正确获取,当重启的次数变的多了以后往往就会考虑到自动重启来解决这种重复的劳动,如:nodemon。那么我们就来探索一下要实现一个类似nodemon的功能。

前提概要:

1. 涉及知识点:

  1. fs.watch,fs.watchFile,chokidar;
  2. child_process,spawn

2. 任务拆解:

  1. 监听文件的改变;
  2. 自动重启服务。

监听文件的改变:

在node的fs包下提供watch和watchFile两个API可以来实现文件和内容变化的监听,但是在nodemon的依赖配置中有这么一个依赖chokidar,通过查看chokidar的说明文档得知如下信息: Node.js fs.watch:

  • 在 MacOS 上不报告文件名。
  • 在 MacOS 上使用 Sublime 等编辑器时根本不报告事件。
  • 重复报告事件。
  • 将大多数更改作为rename。
  • 不提供递归监听文件树的简单方法。
  • 不支持在 Linux 上递归监听。

Node.js fs.watchFile:

  • 在事件处理方面不完美。
  • 不提供任何递归监听。
  • 导致 CPU 使用率高。

我们可以通过chokidar提供的第一个代码片段来实现今天的功能:

const chokidar = require('chokidar');
// One-liner for current directory
chokidar.watch('.').on('all', (event, path) => {
console.log(event, path);
});

自动重启服务:

我们的node服务通常都是通过命令来执行入口文件,所以我们这里就需要使用node中child_process包下的spawn来操作我们的命令,spawn的参数分别是:1.执行的命令,2.命令附带的参数,3.将子进程io对接到父进行进行输出:

function startServer() {
let childProcess = spawn("node", ["index.js"], {
stdio: [process.stdin, process.stdout, process.stderr],
});
console.log("[ starting ] >", `${childProcess}node .index.js`);
}

完整的代码实现:

// watch.js
const chokidar = require("chokidar");
const { spawn } = require("child_process");
let childProcess;
const debounceStartServer = debounce(startServer, 1000);
chokidar.watch(["./index.js"]).on("all", (event, path) => {
childProcess && childProcess.kill();
debounceStartServer();
});
function startServer() {
console.log("[ starting ] >", "node .index.js");
childProcess = spawn("node", ["index.js"], {
stdio: [process.stdin, process.stdout, process.stderr],
});
}
function debounce(fun, wait = 200) {
let timer;
return function () {
const context = this;
const args = arguments;
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
fun.apply(context, args);
}, wait);
};
}
// index.js
const Koa = require("koa");
const app = new Koa();
app.use((ctx) => {
ctx.body = "hi Koa";
});
app.listen(3000);

欢迎关注我的公众号“前端小鑫同学”,原创技术文章第一时间推送。

posted @   前端小鑫同学  阅读(56)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示