監(jiān)聽文件變動
Nodejs中,想要監(jiān)聽文件變動,可以使用內(nèi)置模塊fs的watch方法
該方法可以監(jiān)聽文件或整個文件夾的變動。實例如下:
const restart = _.debounce(() => {
console.log('準(zhǔn)備重啟中...')
kill(child, () => {
startTask()
})
}, 500)
fs.watch(watchPath, restart);
注意:在編輯器中編輯文件時,可能會多次觸發(fā)文件變動,導(dǎo)致一次變動引起數(shù)次回調(diào)的執(zhí)行,如果是重啟node服務(wù)器,就會引起端口占用的問題。所以上面使用了lodash的防抖函數(shù),保證短時間內(nèi)回調(diào)只執(zhí)行一次。
不同平臺下殺死進(jìn)程
在linux和mac系統(tǒng)上,要想殺死子進(jìn)程,可以直接使用child.kill方法,該方法會結(jié)束子進(jìn)程。示例如下:
const childProcess = require('child_process')
const child = childProcess.exec(cmdStr);
child.kill(sinnal);
但是在windows上,child.kill()方法只會結(jié)束cmd,并不會殺死子進(jìn)程。在任務(wù)管理其查看時,能看到任務(wù)仍然在運行。
解決方法是使用子進(jìn)程執(zhí)行一條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退出進(jìn)程時也要殺死創(chuàng)建過的子進(jìn)程
此時需要監(jiān)聽SININT事件,在事件處理函數(shù)中殺死子進(jìn)程并退出主進(jìn)程。如下所示:
process.on("SIGINT", () => {
kill(child, () => {
process.exit();
})
})
- 如果子進(jìn)程之下還有子進(jìn)程,需要將其下所有子進(jìn)程全部殺死。
- 在linux上,使用
child_process執(zhí)行命令可能會出現(xiàn)ENOTE錯誤,則是沒有指定執(zhí)行的選項,以execa為示例:
// linux報錯 命令不可用
const child = execa('node start.js');
// 正確寫法
const child = execa('node start.js', args, {
shell: true
})
即需要指定使用shell運行命令。