Nicholas Kyriakides Nicholas Kyriakides - 5 months ago 22
Node.js Question

Start a shell process in Gulp with callback when process started

I'm trying to run some tasks in Gulp, sequentially. One of those tasks is a shell script that performs a simple

$ node app.js
. How can I fire the callback so I can tell Gulp that the server has started?

tl;dr




So here's the bigger picture of what I'm trying to accomplish:

I'm using gulp run-sequence to fire up a number of tasks sequentially, which specifies a couple ways you should be writing your tasks in order for them to be run in sequence.

Each
gulp.task()
must either:


  • return
    the
    stream

    or

  • call a callback on the task



My setup:




  • gulp.task("clean", ..); // returns the stream, all OK

  • gulp.task("compile", ..); // returns the stream, all OK

  • gulp.task("spin-server", ..); // calls the callback with a hack

  • gulp.task("init-browser-sync", ..); // last task



Here's my
spin-server
task:

gulp.task("spin-server", function(cb) {
exec("sh shell-utilities/spin-server");

// @HACK allow time for the server to start before `runSequence`
// runs the next task.
setTimeout(function() {
cb();
}, 2500);
});


And here's the
spin-server.sh
shell script:

## Start Node server ##

node server/app.js

#######
# EOF #
#######


The problem



Right now I'm using a
setTimeout
hack to make sure my Node/Express server has fired up before proceeding to run the
init-browser-sync
task.

How can I eliminate that
setTimeout
hack and call
cb()
when my Express server actually fires up?

Answer

If you'd like to spawn a process but listen to it's output, you can start it with exec and then attach listeners to the stdout of the process.

var exec = require('child_process').exec;

gulp.task("spin-server", function() {

  var child = exec("sh shell-utilities/spin-server");

  child.stdout.on('data', function(data) {
    console.log('stdout: ' + data);
  });
  child.stderr.on('data', function(data) {
    console.log('stderr: ' + data);
  });
  child.on('close', function(code) {
    console.log('closing code: ' + code);
  });
});