在继续下一个任务之前,让gulp同步写入文件

时间:2014-07-07 20:29:57

标签: javascript node.js gulp

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))
});

正如您所看到的,我具有浏览器捆绑任务,具体取决于响应任务。我相信这可以按预期工作,因为在输出中我看到了:

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

但是,尽管react任务已经完成,但它应该写入操作系统的文件还没有完成。我注意到,如果我在浏览器bundle命令中放入一个sleep语句,那么它会按预期工作,但这对我来说似乎有些笨拙。

如果我希望在将文件(来自gulp.dest)同步写入磁盘之前不认为react任务已完成,我该怎么做?

4 个答案:

答案 0 :(得分:29)

您需要一份退货声明:

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

这样我的所有写操作都在下一个任务处理之前完成。

答案 1 :(得分:1)

回到2019年:如果有人来这里遇到类似的问题

至少在gulp 4. *中,gulp等待promise解决,但忽略结果。 所以...如果您使用异步等待模式并返回gulp.src('...')的结果,您会感到惊讶。任务不等待流完成再继续!可能导致严重错误和时间紧的东西。解决方案是"promisify" gulp.src

示例:


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));
}


答案 2 :(得分:0)

接受的答案是现场,但按照https://github.com/gulpjs/gulp/issues/899,在gulp的3.x分支中,你不能用依赖性来做这件事,而不需要额外的特殊情况:

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'));
});

特别注意使用'run-sequence'模块来强制任务一个接一个地运行。

(如果没有运行,rm -rf build && gulp将导致OK: 0 assertions (0ms),因为tests任务将找不到scripts任务创建的文件,因为它在{{1}之前启动任务完全解决了)

答案 3 :(得分:0)

在这里遇到同样的问题。假设有两个任务,第一个和第二个任务。第二次运行在First之后。 第一个任务生成一些文件,这些文件将由第二个任务读取。使用依赖关系不能确保第二个任务可以找到生成的文件。

我必须明确地在管道上使用done回调让Second只在第一次真正完成之后才开始。

//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();
}

没有done技巧,Second永远不会找到First生成的文件。下面显示了我尝试过的内容,第二个任务可以通过手动调用gulp First找到生成的文件,然后再调用gulp Second

//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();
}