效果展示

Nodemon 源码分析(核心部分)
第一步
- 描述:使用 chokidar 进行文件监听,当文件更改后会触发
filterAndRestart
函数。 - 文件路径:
lib/monitor/watch.js

第二步
- 描述:
filterAndRestart
函数,会通过事件总线
来发送重启Node.js
进程的指令。 - 文件路径:
lib/monitor/watch.js

第三步
- 描述:
事件总线
接收到重启指令后,会触发run.kill
,终止子进程。 - 文件路径:
lib/monitor/run.js

第四步
- 描述:
子进程
退出时,会触发重启函数,从而实现热更新。 - 文件路径:
lib/monitor/run.js

第五步
- 描述:最后看看nodemon一般会通过spawn运行子进程,与主进程进行管道连接。
- 文件路径:
lib/monitor/run.js

实现思路
- 使用chokidar来监听JS文件的修改。
- 通过
event
模块来实现事件总线
,用来跨模块通信。 - 文件修改后,终止当前子进程,然后重新创建一个子进程,与主进程进行管道连接,最终达到热更新效果。
代码实现
第一步
- 先搞一个事件总线,用来提供通信。
- 文件路径:
lib/myNodemon/bus.js
js
const EventEmitter = require('events')
class Bus extends EventEmitter {}
const bus = new Bus();
module.exports = {
bus
}
第二步
- 实现监听函数。
- 文件路径:
lib/myNodemon/watch.js
js
const chokidar = require("chokidar");
const path = require("path");
const { bus } = require("./bus.js");
function watch() {
console.log("开始监听");
const dirs = path.resolve(__dirname, "../../src");
chokidar.watch(dirs).on('add', (path) => {
bus.emit('restart')
})
chokidar.watch(dirs).on("change", (path) => {
bus.emit('restart')
});
}
module.exports = {
watch,
};
第三步
- 在入口文件执行监听、绑定重启函数。
- 文件路径:
lib/myNodemon/main.js
js
const { spawn, exec } = require("child_process");
const { bus } = require("./bus.js");
const { watch } = require("./watch.js");
watch();
let child = undefined;
bus.on("restart", restartChild);
function restartChild() {
console.clear();
console.log(`[${new Date().toLocaleString()}] 已清理命令行内容:`)
if (child) {
child.kill("SIGINT");
if (process.stdin && child.stdin) {
process.stdin.unpipe(child.stdin);
}
if (process.stdout && child.stdout) {
process.stdout.unpipe(child.stdout);
}
}
const binPath = process.cwd() + "/node_modules/.bin" + "/node";
child = spawn("sh", [binPath, process.argv.at(-1)], { stdio: "inherit" });
if (process.stdin && child.stdin) {
process.stdin.pipe(child.stdin);
}
if (process.stdout && child.stdout) {
process.stdout.pipe(child.stdout);
}
}
第四步
- 最后,在
package.json
中配置脚本
json
{
"scripts": {
"dev": "node lib/myNodemon/main.js src/main.js"
}
}
结语
本文记录了作者对nodemon工作原理的学习和了解,文中若有不足的部分欢迎各位大佬进行指导。
😝 打个广告:如果您目前有
合并表格的行/列
需求,可以尝试一下 @jinming6/merge-helper 插件。