siburu
siburu

Reputation: 13

In Gulp, child_process fails to execute a JS program generated by a previous step

I wrote such a gulp script.

In short, this script does:

  1. Clean(remove) a JS program
  2. Build the JS program
  3. Execute the JS program

This script sometimes (not always) fails, but why?

var gulp = require('gulp'),
    babel = require('gulp-babel'),
    rename = require('gulp-rename'),
    concat = require('gulp-concat');

var runSequence = require('run-sequence'),
    del = require('del'),
    exec = require('child_process').exec;

gulp.task('build', function () {
    gulp.src('*.es')
        .pipe(babel())
        .pipe(rename({extname: '.js'}))
        .pipe(gulp.dest('./dist'))
        .pipe(concat('app.js'))
        .pipe(gulp.dest('./dist'));
});

gulp.task('clean', function () {
    del(['dist']);
});

gulp.task('exec', function (cb) {
    exec('node dist/app.js', function (err, stdout, stderr) {
        console.log(stdout);
        console.log(stderr);
        cb(err);
    });
});

gulp.task('default', function (cb) {
    runSequence('clean', 'build', 'exec', cb);
});

The error messages follow:

someone@somewhere:~/***/***% gulp
[15:17:15] Using gulpfile ~/***/***/gulpfile.js
[15:17:15] Starting 'default'...
[15:17:15] Starting 'clean'...
[15:17:15] Finished 'clean' after 4.28 ms
[15:17:15] Starting 'build'...
[15:17:15] Finished 'build' after 12 ms
[15:17:15] Starting 'exec'...

module.js:338
    throw err;
          ^
Error: Cannot find module '/***/***/dist/app.js'
    at Function.Module._resolveFilename (module.js:336:15)
    at Function.Module._load (module.js:278:25)
    at Function.Module.runMain (module.js:501:10)
    at startup (node.js:129:16)
    at node.js:814:3

[15:17:15] 'exec' errored after 119 ms
[15:17:15] Error: Command failed: /bin/sh -c node dist/app.js
module.js:338
    throw err;
          ^
Error: Cannot find module '/***/***/dist/app.js'
    at Function.Module._resolveFilename (module.js:336:15)
    at Function.Module._load (module.js:278:25)
    at Function.Module.runMain (module.js:501:10)
    at startup (node.js:129:16)
    at node.js:814:3

    at ChildProcess.exithandler (child_process.js:751:12)
    at ChildProcess.emit (events.js:110:17)
    at maybeClose (child_process.js:1015:16)
    at Socket.<anonymous> (child_process.js:1183:11)
    at Socket.emit (events.js:107:17)
    at Pipe.close (net.js:485:12)
[15:17:15] 'default' errored after 142 ms
[15:17:15] Error: Command failed: /bin/sh -c node dist/app.js
module.js:338
    throw err;
          ^
Error: Cannot find module '/***/***/dist/app.js'
    at Function.Module._resolveFilename (module.js:336:15)
    at Function.Module._load (module.js:278:25)
    at Function.Module.runMain (module.js:501:10)
    at startup (node.js:129:16)
    at node.js:814:3

    at ChildProcess.exithandler (child_process.js:751:12)
    at ChildProcess.emit (events.js:110:17)
    at maybeClose (child_process.js:1015:16)
    at Socket.<anonymous> (child_process.js:1183:11)
    at Socket.emit (events.js:107:17)
    at Pipe.close (net.js:485:12)

Curiously enough, running "gulp exec" again will succeed.

Upvotes: 1

Views: 953

Answers (1)

Ben
Ben

Reputation: 10104

You need to return the streams you are working with in your tasks so that gulp has a way to know when the tasks are finished:

var gulp = require('gulp'),
    babel = require('gulp-babel'),
    rename = require('gulp-rename'),
    concat = require('gulp-concat');

var runSequence = require('run-sequence'),
    del = require('del'),
    exec = require('child_process').exec;

gulp.task('build', function () {
    return gulp.src('*.es')
        .pipe(babel())
        .pipe(rename({extname: '.js'}))
        .pipe(gulp.dest('./dist'))
        .pipe(concat('app.js'))
        .pipe(gulp.dest('./dist'));
});

gulp.task('clean', function () {
    return del(['dist']);
});

gulp.task('exec', function (cb) {
    exec('node dist/app.js', function (err, stdout, stderr) {
        console.log(stdout);
        console.log(stderr);
        cb(err);
    });
});

gulp.task('default', function (cb) {
    runSequence('clean', 'build', 'exec', cb);
});

Upvotes: 1

Related Questions