Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do some Gulp streams "flow" by default, while others do not?

Consider these two gulp tasks:

gulp.task('src', function(done) {
  gulp.src('docs/*')
    .on('end', function() {
      console.log('ending');
      done();
    });
});

gulp.task('dest', function(done) {
  gulp.src('docs/*')
    .pipe(gulp.dest('temp'))
    .on('end', function() {
      console.log('ending');
      done();
    });
});

Running gulp dest behaves as expected, outputting:

[12:33:15] Using gulpfile ~/Projects/gulp-exit/gulpfile.js
[12:33:15] Starting 'dest'...
ending
[12:33:15] Finished 'dest' after 13 ms

However, running gulp src only outputs:

[12:31:11] Using gulpfile gulpfile.js
[12:31:11] Starting 'src'...

The 'end' callback is never called. After a bit of debugging, I think the stream in the dest task is flowing while the stream in the source task is not.

Signaling the src task to flow explicitly by calling stream.resume():

gulp.task('src', function(done) {
  gulp.src('docs/*')
    .on('end', function() {
      console.log('ending');
      done();
    })
    .resume();
});

Gives the expected output:

[12:46:52] Using gulpfile gulpfile.js
[12:46:52] Starting 'src'...
ending
[12:46:52] Finished 'src' after 11 ms

I've seen this same mix of behaviors with plugins: gulp.dest and gulp-mocha seem to return flowing streams while gulp-logger and gulp-gh-pages do not.

Why the difference in behavior?

like image 958
hurrymaplelad Avatar asked May 09 '26 06:05

hurrymaplelad


1 Answers

The reason why this happens is because some streams have data to be read, and some do not.

gulp.src('docs/*') returns a readable stream with data for each file in docs. The end event only triggers for a readable stream once all the data has been read from the stream.

Normally you would pipe this to another stream which does that automatically, but since you aren't you would need to use:

gulp.task('src', function(done) {
  gulp.src('docs/*')
    .on('data', function() {})
    .on('end', function() {
      console.log('ending');
      done();
    });
});

Alternatively you can use the finish event, which (I think) waits until all data has been pushed into the stream (i.e. it's finished working):

gulp.task('src', function(done) {
  gulp.src('docs/*')
    .on('finish', function() {
      console.log('ending');
      done();
    });
});

Your second gulp task uses gulp.dest('temp') which returns a stream with no data, so end is triggered as soon as the stream is done processing.

like image 196
peterjwest Avatar answered May 11 '26 20:05

peterjwest



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!