I wanted to make a gulpfile to restart a server when files changed. It seemed easy enough at first:
var gulp = require('gulp')
var child = require('child-process')
gulp.task('default', function(){
var ps
function spawn(){
if(ps) ps.kill() //spawn becomes respawn automatically
ps = child.spawn('node', ['.'], {stdio: 'inherit'})
}
spawn()
gulp.watch('*.js', spawn) //respawn on changes.
})
but I then wondered how to improve the logic by handling changes to my gulpfile and this led me to a few discoveries. The big thing I learned was that when you .kill() a child process in node, this sends a SIGTERM, to the process which is a special condition -- you can't catch this in a node script with process.on('exit'), which wasn't obvious to me at first. Eventually I want to further improve this build script by better handling server crashes and I'd like to build a TUI for it all like what I did on the routers project. But for now, the snippet below shows how to build a basic process restart which will automatically fire when files have been changed.
var gulp = require('gulp')
var path = require('path')
var child = require('child_process')
//ANSI escape sequences to provide colors in the terminal.
var ansi = {
red : "\x1b[31m",
green : "\x1b[32m",
yellow : "\x1b[33m",
blue : "\x1b[34m",
purple : "\x1b[35m",
teal : "\x1b[36m",
grey : "\x1b[37m",
reset : "\x1b[0m"
}
gulp.task('runServer', function(){
var ps
function spawn(){
if(ps){
console.log(ansi.yellow,"killing server",ansi.reset)
ps.kill()
}
ps = child.spawn('node', ['.'], {stdio: 'inherit'})
ps.on('exit', function(code, signal){
if(signal) console.log(ansi.yellow,
"server received",signal,ansi.reset)
console.log(ansi.yellow,
"server exited with", code, ansi.reset)
if(code !== 143){ //exit code 143 indicates SIGTERM.
console.log(ansi.red,
"***Looks like the server crashed.",
"We'll try to restart it on the next file save.",ansi.reset)
}
})
console.log(ansi.yellow, "server started", ansi.reset)
}
spawn()
gulp.watch('*.js', function(event){
//don't watch gulpfile in this context:
if(event.path === path.join(__dirname, "gulpfile.js")) return;
spawn()
})
process.on('SIGTERM', function(){
if(ps){
console.log(ansi.yellow,
"killing server due to SIGTERM",ansi.reset)
ps.kill()
}
})
})
gulp.task('default', function(){
var ps
function spawn(){
if(ps) ps.kill()
ps = child.spawn('gulp', ['runServer'], {stdio: 'inherit'})
}
spawn()
gulp.watch('gulpfile.js', function(event){
spawn()
})
})