簡體   English   中英

如何一個接一個地按順序運行 Gulp 任務

[英]How to run Gulp tasks sequentially one after the other

在這樣的片段中:

gulp.task "coffee", ->
    gulp.src("src/server/**/*.coffee")
        .pipe(coffee {bare: true}).on("error",gutil.log)
        .pipe(gulp.dest "bin")

gulp.task "clean",->
    gulp.src("bin", {read:false})
        .pipe clean
            force:true

gulp.task 'develop',['clean','coffee'], ->
    console.log "run something else"

develop任務中,我想clean地運行,完成后,運行coffee ,完成后,運行其他東西。 但我想不通。 這一段不行。 請指教。

默認情況下,gulp 同時運行任務,除非它們有明確的依賴關系。 這對於像clean這樣的任務不是很有用,在那里你不想依賴,但你需要它們在其他一切之前運行。

我專門編寫run-sequence插件來解決 gulp 的這個問題。 安裝后,像這樣使用它:

var runSequence = require('run-sequence');

gulp.task('develop', function(done) {
    runSequence('clean', 'coffee', function() {
        console.log('Run something else');
        done();
    });
});

您可以閱讀包 README 上的完整說明——它還支持同時運行一些任務集。

請注意,這將在 gulp 的下一個主要版本中(有效地)修復,因為它們完全消除了自動依賴排序,並提供了類似於run-sequence工具,允許您手動指定所需的運行順序。

然而,這是一個重大的突破性變化,所以沒有理由等待今天可以使用run-sequence

這個問題唯一好的解決方案可以在 gulp 文檔中找到:

var gulp = require('gulp');

// takes in a callback so the engine knows when it'll be done
gulp.task('one', function(cb) {
  // do stuff -- async or otherwise
  cb(err); // if err is not null and not undefined, the orchestration will stop, and 'two' will not run
});

// identifies a dependent task must be complete before this one begins
gulp.task('two', ['one'], function() {
  // task 'one' is done now
});

gulp.task('default', ['one', 'two']);
// alternatively: gulp.task('default', ['two']);

它尚未正式發布,但即將推出的 Gulp 4.0 可讓您輕松地使用 gulp.series 執行同步任務。 你可以簡單地這樣做:

gulp.task('develop', gulp.series('clean', 'coffee'))

我找到了一篇很好的博客文章,介紹了如何升級和利用這些簡潔的功能:通過示例遷移到 gulp 4

我使用generator-gulp-webapp Yeoman 生成器生成了一個節點/gulp 應用程序。 它以這種方式處理了“干凈的難題”(轉換為問題中提到的原始任務):

gulp.task('develop', ['clean'], function () {
  gulp.start('coffee');
});

run-sequence是最清晰的方式(至少在 Gulp 4.0 發布之前)

使用 run-sequence ,您的任務將如下所示:

var sequence = require('run-sequence');
/* ... */
gulp.task('develop', function (done) {
    sequence('clean', 'coffee', done);
});

但是如果你(出於某種原因)不想使用它, gulp.start方法會有所幫助

gulp.task('develop', ['clean'], function (done) {
    gulp.on('task_stop', function (event) {
        if (event.task === 'coffee') {
            done();
        }
    });
    gulp.start('coffee');
});

注意:如果你只開始任務而不聽結果, develop任務會比coffee更早完成,這可能會造成混淆。

您也可以在不需要時刪除事件偵聽器

gulp.task('develop', ['clean'], function (done) {
    function onFinish(event) {
        if (event.task === 'coffee') {
            gulp.removeListener('task_stop', onFinish);
            done();
        }
    }
    gulp.on('task_stop', onFinish);
    gulp.start('coffee');
});

考慮到您可能還想收聽task_err事件 task_stop在成功完成時觸發,而task_err在出現錯誤時出現。

您可能還想知道為什么gulp.start()沒有官方文檔。 gulp 成員的這個回答解釋了這些事情:

gulp.startgulp.start沒有記錄的,因為它會導致復雜的構建文件,我們不希望人們使用它

(來源:https ://github.com/gulpjs/gulp/issues/426#issuecomment-41208007

根據 Gulp 文檔:

您的任務是否在依賴項完成之前運行? 確保您的依賴任務正確使用異步運行提示:接收回調或返回承諾或事件流。

要同步運行您的任務序列:

  1. 將事件流(例如gulp.src )返回給gulp.task以通知任務流何時結束。
  2. gulp.task的第二個參數中聲明任務依賴gulp.task

查看修改后的代碼:

gulp.task "coffee", ->
    return gulp.src("src/server/**/*.coffee")
        .pipe(coffee {bare: true}).on("error",gutil.log)
        .pipe(gulp.dest "bin")

gulp.task "clean", ['coffee'], ->
      return gulp.src("bin", {read:false})
        .pipe clean
            force:true

gulp.task 'develop',['clean','coffee'], ->
    console.log "run something else"

我遇到了完全相同的問題,結果對我來說解決方案非常簡單。 基本上將您的代碼更改為以下內容,它應該可以工作。 注意:gulp.src 之前的返回對我來說完全不同。

gulp.task "coffee", ->
    return gulp.src("src/server/**/*.coffee")
        .pipe(coffee {bare: true}).on("error",gutil.log)
        .pipe(gulp.dest "bin")

gulp.task "clean",->
    return gulp.src("bin", {read:false})
        .pipe clean
            force:true

gulp.task 'develop',['clean','coffee'], ->
    console.log "run something else"

嘗試了所有提出的解決方案,似乎都有自己的問題。

如果您實際查看 Orchestrator 源代碼,尤其是.start()實現,您會發現如果最后一個參數是一個函數,它會將其視為回調。

我為我自己的任務寫了這個片段:

  gulp.task( 'task1', () => console.log(a) )
  gulp.task( 'task2', () => console.log(a) )
  gulp.task( 'task3', () => console.log(a) )
  gulp.task( 'task4', () => console.log(a) )
  gulp.task( 'task5', () => console.log(a) )

  function runSequential( tasks ) {
    if( !tasks || tasks.length <= 0 ) return;

    const task = tasks[0];
    gulp.start( task, () => {
        console.log( `${task} finished` );
        runSequential( tasks.slice(1) );
    } );
  }
  gulp.task( "run-all", () => runSequential([ "task1", "task2", "task3", "task4", "task5" ));

我一直在尋找這個答案。 現在我在官方的 gulp 文檔中得到了它。

如果你想在最后一個任務完成時執行 gulp 任務,你必須返回一個流:

 gulp.task('wiredep', ['dev-jade'], function () { var stream = gulp.src(paths.output + '*.html') .pipe($.wiredep()) .pipe(gulp.dest(paths.output)); return stream; // execute next task when this is completed }); // First will execute and complete wiredep task gulp.task('prod-jade', ['wiredep'], function() { gulp.src(paths.output + '**/*.html') .pipe($.minifyHtml()) .pipe(gulp.dest(paths.output)); });

簡單地做coffeecleandevelopcoffee

gulp.task('coffee', ['clean'], function(){...});
gulp.task('develop', ['coffee'], function(){...});

Dispatch 現在是連續的: cleancoffeedevelop 請注意, clean的實現和coffee的實現必須接受回調, “因此引擎知道何時完成”

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

總之,下面是一個簡單的 gulp 模式,用於同步clean后跟異步構建依賴項

//build sub-tasks
gulp.task('bar', ['clean'], function(){...});
gulp.task('foo', ['clean'], function(){...});
gulp.task('baz', ['clean'], function(){...});
...

//main build task
gulp.task('build', ['foo', 'baz', 'bar', ...], function(){...})

Gulp 足夠聰明,每次build運行一次clean ,無論build的依賴項有多少依賴於clean 如上所述, clean是一個同步障礙,然后所有build的依賴項並行運行,然后build運行。

對我來說,它沒有在連接后運行 minify 任務,因為它期望連接輸入並且它沒有生成幾次。

我嘗試按執行順序添加到默認任務,但沒有奏效。 它在為每個任務添加一個return並在gulp.start()獲得縮小后工作,如下所示。

/**
* Concatenate JavaScripts
*/
gulp.task('concat-js', function(){
    return gulp.src([
        'js/jquery.js',
        'js/jquery-ui.js',
        'js/bootstrap.js',
        'js/jquery.onepage-scroll.js',
        'js/script.js'])
    .pipe(maps.init())
    .pipe(concat('ux.js'))
    .pipe(maps.write('./'))
    .pipe(gulp.dest('dist/js'));
});

/**
* Minify JavaScript
*/
gulp.task('minify-js', function(){
    return gulp.src('dist/js/ux.js')
    .pipe(uglify())
    .pipe(rename('ux.min.js'))
    .pipe(gulp.dest('dist/js'));
});

gulp.task('concat', ['concat-js'], function(){
   gulp.start('minify-js');
});

gulp.task('default',['concat']); 

來源http://schickling.me/synchronous-tasks-gulp/

Gulp 和 Node 使用promises

所以你可以這樣做:

// ... require gulp, del, etc

function cleanTask() {
  return del('./dist/');
}

function bundleVendorsTask() {
  return gulp.src([...])
    .pipe(...)
    .pipe(gulp.dest('...'));
}

function bundleAppTask() {
  return gulp.src([...])
    .pipe(...)
    .pipe(gulp.dest('...'));
}

function tarTask() {
  return gulp.src([...])
    .pipe(...)
    .pipe(gulp.dest('...'));
}

gulp.task('deploy', function deployTask() {
  // 1. Run the clean task
  cleanTask().then(function () {
    // 2. Clean is complete. Now run two tasks in parallel
    Promise.all([
      bundleVendorsTask(),
      bundleAppTask()
    ]).then(function () {
      // 3. Two tasks are complete, now run the final task.
      tarTask();
    });
  });
});

如果返回 gulp 流,則可以使用then()方法添加回調。 或者,您可以使用 Node 的原生Promise來創建您自己的Promise 在這里,我使用Promise.all()來實現一個回調,當所有Promise.all()都解決時會觸發該回調。

等待看看任務是否完成,然后剩下的,我是這樣的:

gulp.task('default',
  gulp.series('set_env', gulp.parallel('build_scss', 'minify_js', 'minify_ts', 'minify_html', 'browser_sync_func', 'watch'),
    function () {
    }));

榮譽: https : //fettblog.eu/gulp-4-parallel-and-series/

我發現一個接一個地執行任務的非常簡單有效的解決方案(當一個任務完成時,第二個任務將被啟動)(僅提供一個例子)是:
gulp.task('watch', () =>
gulp.watch(['src/**/*.css', 'src/**/*.pcss'], gulp.series('build',['copy'])) );
這意味着當您需要在second-task first-task之前運行first-task ,您需要將第二個任務(在這種情況下為copy )寫在方括號中。
筆記
任務的外部應該有圓括號(直到您希望它們同時發生)

試試這個 hack :-) Gulp v3.x Hack for Async bug

我嘗試了自述文件中的所有“官方”方法,它們對我不起作用,但確實如此。 你也可以升級到 gulp 4.x 但我強烈建議你不要,它破壞了很多東西。 您可以使用真正的 js 承諾,但是,嘿,這是快速、骯臟、簡單的 :-) 基本上您使用:

var wait = 0; // flag to signal thread that task is done
if(wait == 0) setTimeout(... // sleep and let nodejs schedule other threads

看看帖子!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM