I'm trying to use the module grunt-contrib-watch to restart my node.js server whenever certain files change. I already use grunt to run the server, jshint, and the template compiler, and I know those functions work. Here's the task to start the server:
grunt.registerTask('runServer', 'Starts the server.', function(){
grunt.log.writeln('Starting server...');
var done = this.async();
var child = grunt.util.spawn({
cmd: process.argv[0],
args: ['server.js'],
}, function(){
grunt.log.writeln('Server stopped!');
done(true);
});
child.stdout.pipe(process.stdout);
child.stderr.pipe(process.stderr);
});
Here's the config for the watch task:
watch: {
all: {
files: ['some/files/*.js'],
tasks: ['default'],
options: {
spawn: true,
interrupt: true,
reload: true,
}
}
}
When the task is restarted, the server fails because of an "EADDRINUSE" exception, which I take to mean is because the previous child process didn't release the port it was using, which is strange - I do see the "Server stopped!" message. I have tried this with all combinations of the three options, and I looked on the github page for grunt-contrib-watch, and nothing showed anything. How can I make the interrupted node.js process close all its resources before the next one tries to start?
Is it necessary to perform a child process spawn? In every case that I have spun up a server, I have simply done something like this:
grunt.registerTask('runServer', 'Starts the server.', require('./server'));
The watch task remains the same as you have it listed. Grunt automatically kills the previous run of that task as long as it is not a child process. This seems to work just fine for me.
However, if you NEED to spawn a child process and then kill it:
var spawn = require('child_process').spawn,
server = undefined;
...
grunt.registerTask('runServer', 'Starts the server.', function(){
grunt.log.writeln('Starting server...');
if (server)
server.kill('SIGUSR2');
server = spawn('node', ['server.js'], {stdio: 'inherit'});
}
...
grunt.registerTask('default', ['runServer']);