순차적으로 Gulp 작업을 순차적으로 실행하는 방법


398

스 니펫에서 다음과 같이 :

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하고이 끝나면, 다른 뭔가를 실행합니다. 그러나 나는 그것을 알아낼 수 없습니다. 이 작품은 작동하지 않습니다. 조언 부탁드립니다.


10
run-sequence npm 모듈은 이제이 문제를 해결합니다. 다른 모든 답변은 이제 관련이 없습니다. 아래 OverZealous의 답변 참조
danday74

1
Gulp 4.0은 기본적으로 실행 작업을 순서대로 지원하여 run-sequence더 이상 사용되지 않습니다. 아래의 massanishi의 답변 참조
Forivin

Gulp4는 수정하는 것보다 더 많은 것을 깨뜨립니다. 몇 시간 동안 싸운 후 다시 3.9.1로 돌아갑니다. 나는 주요 버전이 백 컴 패트를 깨뜨릴 수 있음을 알고 있지만 암호가없고 쓸모없는 오류 메시지로 감사합니다. v4가 준비되지 않았습니다.
토 티루

답변:


121

아직 공식 릴리스는 아니지만 곧 출시 될 Gulp 4.0을 사용하면 gulp.series를 사용하여 동기 작업을 쉽게 수행 할 수 있습니다. 다음과 같이 간단하게 수행 할 수 있습니다.

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

예를 들어 gulp 4로 마이그레이션하는 방법과 깔끔한 ​​기능을 사용하는 방법을 소개하는 좋은 블로그 게시물을 발견했습니다.


3
모든 신규 이민자를위한 선택 방법. 그들은 정말로 gulp 4로 시작해야하며 모든 3. * 번거롭고 광범위한 반 패턴을 건너 뜁니다.
metalim

187
2017 년에도 여전히 소개하지 않았습니다. 큰.
Tomasz Mularczyk

14
나는 요점을 실제로 보지 못한다. B가 실행 된 후에 만 ​​A를 실행해야하는 경우 A는 B에 의존합니다. B가 A의 종속성이라는 것을 지정할 수없는 이유는 무엇입니까? gulp.task('coffee', ['clean'], function(){...}); gulp.task('develop', ['coffee']);
musicin3d

3
@ musicin3d 당신이 말하는 것은 효과가 있지만, 당신은 하나의 작업을 반드시 이전의 것과 결합하고 있습니다. 예를 들어, 항상 보푸라기없이 빌드 할 수 있기를 원합니다. 독립적 인 작업을 수행하고 외부 도구를 사용하여 실행 순서를 결정하는 것이 더 나은 솔루션입니다.
AxeEffect

11
2018 년과 마침내 그것을 소개했습니다. 큰.
dargmuesli

411

기본적으로 gulp는 명시적인 종속성이없는 한 동시에 작업을 실행합니다. clean의존하지 않으려는 작업과 같은 작업에는 유용 하지 않지만 다른 작업보다 먼저 실행해야합니다.

gulp 로이 문제를 해결하기 위해 플러그인을 특별히 작성 했습니다run-sequence . 설치 한 후 다음과 같이 사용하십시오.

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오늘 사용할 수있을 때까지 기다릴 이유가 없습니다 .


2
플러그인에 대한 @OverZealous 감사합니다! Btw, gulp-clean플러그인이 Streams 2를 구현하지 않았기 때문에 종속성으로 실행되는 데 문제가있었습니다. 이 문제는 릴리스 버전 0.3.0에서 수정되었으며 동료가 PR을 제출하여이를 변환했습니다.
knownasilya

3
@Indolering 기본 제공 작업 종속성 기능은 이 시나리오를 해결 하지 못합니다 . 더 행에서이 작업을 실행하는 방법이으로 구축 : 종속 작업은 항상 실행되지 않습니다 약간의 시간을,하지만 모든 시간을. run-sequence꿀꺽 꿀꺽 빠뜨린 중요한 기능을 해결합니다.
OverZealous

2
또한 작업 종속성은 완벽한 솔루션이 아닙니다. 데이터베이스를 사용하여 독립적으로 테스트를 실행하는 두 가지 gulp 작업이 있다고 가정 해보십시오. 둘 다 다른 것에 의존하지 않지만 둘 다 데이터베이스를 사용해야하기 때문에 둘 다 동시에 실행하고 싶지 않습니다.
peterjwest

3
놀라운 모듈-여기 왜 필요한지에 대한 훌륭한 설명이 있습니다.- blog.mdnbar.com / gulp - for - simple - build - proccess- 이것은 정답입니다
danday74

5
이에 대한 해결책을 마련해 주셔서 감사하지만 순차적 실행을 위해서는 추가 툴링이 필요합니다. 순차적 실행은 기본값이거나 최소한 쉬운 작업이어야합니다. Makefile은 40 년 동안 순차적으로 실행되었습니다. JS 생태계는 나를 아프게한다. 기능이없는 상용구 프로젝트를 컴파일하기위한 73MB의 node_modules는 여전히 순차 실행 기능을 포함하지 않습니다. 운영 체제는 더 작은 공간에 적합하며 커널 및 드라이버 FFS가 있습니다.
joonas.fi

371

이 문제에 대한 유일한 좋은 해결책은 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']);

6
어떤 이유로 작업 ReferenceError: err is not defined에서이 gulp-compass작업 을 실행하려고하는데 뭔가 빠졌습니까?
waffl

11
@waffl이 예제는 콜백을 사용하는데, 이것이 유일한 방법은 아닙니다. 문서 에 따르면 "엔진이 각각 해결 또는 종료 대기해야한다는 약속 또는 스트림을 반환 할 수도 있습니다." 따라서 작업 1에서 스트림을 반환하는 경우 (예 :)는 작업 2를 return gulp.src('app/**/*.js').pipe(concat(app.js)).pipe(gulp.dest('app/scripts');정의 할 때 작업 1을 종속 항목으로 식별하는 것입니다. gulp.task('two', ['one'], function() {...작업 2는 이제 작업 1이 종료되기를 기다렸다가 실행합니다.
esvendsen

24
이것은 '1'과 '2'사이의 긴밀한 결합을 만듭니다. 'one'을 실행하지 않고 'two'를 실행하려면
wilk

5
종속성없이 새 작업을 정의 하시겠습니까?
Mathieu Borderé

8
순차적으로 실행하기 위해 두 가지 작업이 필요하다는 것은 긴밀한 결합을 의미합니다.
Ringo

56

generator-gulp-webapp Yeoman 생성기를 사용하여 노드 / gulp 앱을 생성했습니다. 그것은 "깨끗한 수수께끼"를 이런 식으로 처리했습니다 (질문에 언급 된 원래 작업으로 번역).

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

2
이것은 내가 필요로 한 정확하고 매우 간단했습니다. 이 작업에 대한 종속성으로 clean을 설정하지 않고 종속성을 빌드하기 위해 선행 종속성으로 clean과 같은 작업을 수행 해야하는 시나리오를 해결합니다. 추신 : gulp.start () 비트에 대한 정보-경고 : github.com/gulpjs/gulp/issues/426
Jaans

말이 되네요. 기본 작업 (및 종속 작업)이 완료된 후의 콜백 감사.
markau

4
에 대한 공식 문서가없는 이유를 누군가가 궁금해하는 경우 gulp.start(), 꿀꺽 회원에서이 답변이 설명 : gulp.start is undocumented on purpose because it can lead to complicated build files and we don't want people using it(출처 : github.com/gulpjs/gulp/issues/426#issuecomment-41208007 )
thybzi

1
이 경우 coffee작업이 완료 되었음을 어떻게 알 수 있습니까? 내가 그것을 감지하지 못하면, develop작업은보다 일찍 완료됩니다coffee
thybzi

이미 run-sequence소스 코드 에서 답변을 얻었습니다 gulp.on('task_stop'). 자세한 내용은 확장 답변을 참조하십시오. stackoverflow.com/a/38818657/3027390
thybzi

32

실행 순서 는 가장 명확한 방법입니다 (적어도 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.start 복잡한 빌드 파일로 이어질 수 있기 때문에 의도적으로 문서화되지 않았습니다.

(출처 : https://github.com/gulpjs/gulp/issues/426#issuecomment-41208007 )


이 사람에게 커피 두 잔! 청취자를 제거하는 솔루션은 완벽하게 작동합니다!
daniel.bavrin

이것이 실제로 정답입니다. "gulp 4"입니다. 실행 순서가 강력합니다.
LAdams87

26

Gulp 문서에 따르면 :

종속성이 완료되기 전에 작업이 실행 중입니까? 종속성 작업이 비동기 실행 힌트를 올바르게 사용하고 있는지 확인하십시오. 콜백을 받거나 약속 또는 이벤트 스트림을 반환하십시오.

일련의 작업을 동기식으로 실행하려면

  1. 이벤트 스트림을 반환합니다 (예 : gulp.src 하는) gulp.task경우 스트림 끝의 작업을 알리기 위해.
  2. 두 번째 인수에서 작업 종속성 선언 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"

4
이것이 정답이어야합니다! 귀환 작업은 트릭을했다! 고마워요
Dzoukr

10

나는이 똑같은 문제를 겪고 있었고 해결책은 꽤 쉽다는 것이 밝혀졌다. 기본적으로 코드를 다음과 같이 변경하면 작동합니다. 참고 : 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"

돌아 오는 것에 대한 메모 주셔서 감사합니다! 왜 꿀꺽 꿀꺽 거리는 작업이 잘못되었는지 알아 내려고 노력하고있었습니다.
Andrew F

작업 사이의 긴밀한 연결을 피하려면 정답이어야합니다. 잘 작동합니다. 4.0에서 사용할 수있는 gulp.series가 아마도 가장 좋은 대답 일 것입니다. 그러나 현재로서는 4.0을 사용할 수 없습니다.
wilk

첫 번째 청소 또는 커피를 실행할 개발 꿀꺽
풍경

8

제안 된 모든 솔루션을 시도했지만 모두 자체 문제가있는 것 같습니다.

실제로 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" ));

4

나는이 답변을 잠시 동안 찾고있었습니다. 이제 공식 펄프 문서에서 얻었습니다.

마지막 작업이 완료되었을 때 꿀꺽 꿀꺽 작업을 수행하려면 스트림을 반환해야합니다.

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


3

간단하게 coffee의존 clean하고 develop에 따라 달라집니다 coffee:

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

파견은 이제 시리얼 : cleancoffeedevelop. 주의 clean의 구현과 coffee의 구현 해야한다 , 콜백을 받아 "그것을 할 것이다 때 엔진이 알 수 있도록" :

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

결론적으로, 아래는 비동기 빌드 의존성이 따르는 동기에 대한 간단한 펄프 패턴입니다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는 얼마나 많은 종속성이 의존 하든 관계없이 clean정확히 한 번만 실행할 수 있을 정도로 똑똑 합니다 . 위에서 쓴 것처럼 동기화 장벽이 있고 모든 종속성이 병렬로 실행 된 다음 실행됩니다.buildbuildcleancleanbuildbuild


3

나를 위해 연결 된 입력을 예상하고 연결이 생성되지 않았기 때문에 연결 후 축소 작업을 실행하지 않았습니다.

실행 순서대로 기본 작업에 추가하려고 시도했지만 작동하지 않았습니다. 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/


2

Gulp와 Node는 약속을 사용 합니다 .

그래서 당신은 이것을 할 수 있습니다 :

// ... 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.all()모든 약속이 해결되면 발생하는 콜백이 하나 있습니다.


-8

버그를 사용해보십시오 :-) 비동기 버그 용 Gulp v3.x 핵

나는 Readme의 모든 "공식적인"방법을 시도했지만 그들은 나를 위해 일하지 않았지만 이것은 효과가있었습니다. gulp 4.x로 업그레이드 할 수도 있지만 그렇게하지 않는 것이 좋습니다. 진짜 js promise를 사용할 수는 있지만, 이것은 빠르고 더럽고 간단합니다 :-) 본질적으로 다음을 사용합니다.

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

게시물을 확인하십시오!


setTimeout을 사용하지 않는 것이 문제를 해결하는 더 좋은 방법이 있습니다. 작업을 완료하는 데 걸리는 시간을 정확히 알 수 없었습니다.
Reginaldo Camargo Ribeiro

코드 pff를 작성하기 전에 정말로 생각해야합니다
DDD
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.