Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making gulp write files synchronously before moving on to the next task

gulpfile.js

gulp.task('browser-bundle', ['react'], function() {
...

});


gulp.task('react', function(){
  gulp.src(options.JSX_SOURCE)
      .pipe(react())
      .pipe(gulp.dest(options.JSX_DEST))
});

As you can see I have the browser-bundle task depending on the react task. I believe this works as expected because in the output I see this:

[gulp] Running 'react'...
[gulp] Finished 'react' in 3.43 ms
[gulp] Running 'browser-bundle'...

However, although the react task is finished, the files its supposed to write to the operating system are not quite there yet. I've notice that if I put a sleep statement in the browser bundle command then it works as expected, however this seems a little hacky to me.

If I want the react task to not be considered finished until the files (from gulp.dest) have been synchronously written to disk how would I do that?

like image 831
asolberg Avatar asked Jul 07 '14 20:07

asolberg


4 Answers

You need a return statement:

gulp.task('react', function(){
    return gulp.src(options.JSX_SOURCE)
        .pipe(react())
        .pipe(gulp.dest(options.JSX_DEST))
});

With this all my write operations are done before the next task processed.

like image 139
RWAM Avatar answered Oct 22 '22 10:10

RWAM


back to 2019: if some one come here with similar problem

In gulp 4.*, at least, gulp wait for promise to resolve but ignore the result. so... if you use async await pattern and return the result of gulp.src('...') you got a surprise. the task not wait for stream finish before it continue! somthing that can result to serious bug and waist of time. the solution is "promisify" gulp.src

example:


gulp.task( async function notWaitingTask(){
   // the return stream are ignored because function return promise not stream
   return gulp.src('file.js')
     .pipe(gulp.dest('new-location'))

})

gulp.task( async function waitingTask(){
   // the return stream are respect

   await promisifyStream(
     gulp.src('file.js')
      .pipe(gulp.dest('new-location'))
   )

})

function promisifyStream(stream) {
    return new Promise( res => stream.on('end',res));
}


like image 33
pery mimon Avatar answered Oct 22 '22 10:10

pery mimon


The accepted answer is spot on, but as per https://github.com/gulpjs/gulp/issues/899, in the 3.x branch of gulp, you cannot do this with dependencies without a bit of extra special sauce:

var run = require('run-sequence');
var nodeunit = require('gulp-nodeunit');
var babel = require('gulp-babel');
var gulp = require('gulp');

/// Explicitly run items in order
gulp.task('default', function(callback) {
  run('scripts', 'tests', callback);
});

/// Run tests
gulp.task('tests', function() {
  return gulp.src('./build/**/*.tests.js').pipe(nodeunit());
});

// Compile ES6 scripts using bable
gulp.task('scripts', function() {
  return gulp.src('./src/**/*.js')
    .pipe(babel())
    .pipe(gulp.dest('./build'));
});

Notice specifically the use of the 'run-sequence' module to force the tasks to run one after another, as well.

(Without run, rm -rf build && gulp will result in OK: 0 assertions (0ms) because the tests task will not find the files created by the scripts task because it starts before the scripts task is completely resolved)

like image 1
Doug Avatar answered Oct 22 '22 12:10

Doug


Met same issue here. Let's say there are 2 tasks, First and Second. Second runs after First. The First task generates some files, which are to be read by the Second task. Using dependency doesn't make sure the Second task can find the files generated.

I have to explicitly using the done callback on the pipeline to let Second only starts after First truly done.

//This approach works!
gulp.task('First', function(done)) {
   var subFolders = fs.readdirSync(somefolder)...
   var tasksForFolders = subFolders.map(function(folder) {
       return gulp.src('folder/**/*').sthtogeneratefiles();
   });
   tasksForFolders[tasksForFolders.length-1].on('end',done);
   return tasksForFolders;
}

gulp.task('Second', ['First'],function() {
    return gulp.src('generatedfolders/**/*').doth();
}

Without the done trick, the Second never finds the files generated by First. Below shows what I tried, the Second task can find the files generated by calling gulp First by hand, and then calling gulp Second subsequently.

//This is the WRONG approach, just for demonstration!!
gulp.task('First', function()) {
   var subFolders = fs.readdirSync(somefolder)...
   var tasksForFolders = subFolders.map(function(folder) {
       return gulp.src('folder/**/*').sthtogeneratefiles();
   });
   return tasksForFolders;
}

gulp.task('Second', function() {
    return gulp.src('generatedfolders/**/*').doth();
}
like image 1
Popeye Avatar answered Oct 22 '22 12:10

Popeye