Running Node app through Grunt

I am trying to run my Node application as a Grunt task. I need to spawn this as a child process, however, to allow me to run the watch task in parallel.

This works:

grunt.registerTask('start', function () {
  grunt.util.spawn(
    { cmd: 'node'
    , args: ['app.js']
    })

  grunt.task.run('watch:app')
})

However, when changes are detected by the watch task, this will trigger the start task again. Before I spawn another child process of my Node app, I need to kill the previous one.

I can't figure out how to kill the process, however. Something like this does not work:

var child

grunt.registerTask('start', function () {
  if (child) child.kill()
  child = grunt.util.spawn(
    { cmd: 'node'
    , args: ['app.js']
    })

  grunt.task.run('watch:app')
})

It appears that:

  1. Even though I store the spawned process in a variable outside of the function context, it does not persist, so the next time the start task is run, child is undefined.
  2. child has no kill function…

This is because grunt-contrib-watch currently spawns all task runs as child processes. So the variable child is not within the same process context. Fairly soon, grunt-contrib-watch@0.3.0 will be released with a nospawn option. This will let you configure the watch to spawn task runs within the same context and would make your above example work.

Take a look at this issue for a little more information:

https://github.com/gruntjs/grunt-contrib-watch/issues/45

Take a look at grunt-nodemon which handles a lot of the headaches related to spawning a child process.