Reputation: 22939
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
orgulp.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 #
#######
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?
Upvotes: 3
Views: 1559
Reputation: 18937
var exec = require('child_process').exec;
gulp.task('spin-server', function (cb) {
exec('sh shell-utilities/spin-server', function (err, stdout, stderr) {
console.log(stdout);
console.log(stderr);
if (err || stdout.indexOf('runSequence') > -1) {
cb(err);
}
});
})
Upvotes: 0
Reputation: 19173
Use spawn
instead of exec
(require('child_process').spawn
) like this :
var spawn = require('child_process').spawn;
gulp.task("spin-server", function(cb) {
var srv = spawn("sh shell-utilities/spin-server");
srv.stdout.on('data', data => {
if(data.includes('server listening')) { // Or whatever your server outputs when it's done initializing
console.log('Server initialization completed');
return cb();
}
});
});
When the string server listening
is found in the output of the spawned process, the cb()
is called and the server is guaranteed to be initialized at that point.
Upvotes: 3
Reputation: 6145
gulp.task("spin-server", function(cb) {
const spawn = require('child_process').spawn;
const process = spawn('bash', ['', 'setup.sh']);
process.stdout.on('data', (data) => {
if(data = "SCRIPT CHECKPOINT")
cb();
});
});
Use spawn
for non blocking async exec.
Let your setup.sh
file print "SCRIPT CHECKPOINT"
or something similar to inform that the server is up and running".
This will trigger the cb()
.
Upvotes: 2
Reputation: 5417
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);
});
});
Upvotes: 2