监听文件变动
Nodejs中,想要监听文件变动,可以使用内置模块fs
的watch
方法
该方法可以监听文件或整个文件夹的变动。实例如下:
const restart = _.debounce(() => {
console.log('准备重启中...')
kill(child, () => {
startTask()
})
}, 500)
fs.watch(watchPath, restart);
注意:在编辑器中编辑文件时,可能会多次触发文件变动,导致一次变动引起数次回调的执行,如果是重启node服务器,就会引起端口占用的问题。所以上面使用了lodash
的防抖函数,保证短时间内回调只执行一次。
不同平台下杀死进程
在linux
和mac
系统上,要想杀死子进程,可以直接使用child.kill
方法,该方法会结束子进程。示例如下:
const childProcess = require('child_process')
const child = childProcess.exec(cmdStr);
child.kill(sinnal);
但是在windows
上,child.kill()
方法只会结束cmd
,并不会杀死子进程。在任务管理其查看时,能看到任务仍然在运行。
解决方法是使用子进程执行一条windows
命令(taskkill
)。如下所示:
async function kill(child, callback) {
if (process.platform === "win32") {
const _child = execa('taskkill /pid ' + child.pid + ' /T /F', [], {
shell: true,
cwd
});
try {
await _child;
} catch (e) {
console.log('error: ', e);
}
callback();
} else {
child.kill();
callback();
}
}
注意点:
- 在按ctrl+c退出进程时也要杀死创建过的子进程
此时需要监听SININT
事件,在事件处理函数中杀死子进程并退出主进程。如下所示:
process.on("SIGINT", () => {
kill(child, () => {
process.exit();
})
})
- 如果子进程之下还有子进程,需要将其下所有子进程全部杀死。
- 在linux上,使用
child_process
执行命令可能会出现ENOTE错误,则是没有指定执行的选项,以execa为示例:
// linux报错 命令不可用
const child = execa('node start.js');
// 正确写法
const child = execa('node start.js', args, {
shell: true
})
即需要指定使用shell运行命令。