क्रमिक रूप से एक के बाद एक गुल्प कार्यों को कैसे चलाया जाए


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
रन-सीक्वेंस npm मॉड्यूल इस समस्या को अब ठीक कर देता है - अन्य सभी उत्तर अब अप्रासंगिक हैं - नीचे देखें OverZealous का उत्तर
danday74

1
गुल्प 4.0 मूल रूप से अनुक्रम में चल रहे कार्यों का समर्थन करता है, run-sequenceअप्रचलित प्रतिपादन करता है - नीचे मासनिस्सी का उत्तर देखें
Forivin

इसे ठीक करने से ज्यादा चीजें गुलप 4 तोड़ती हैं, ऐसा लगता है। कुछ घंटों तक इससे जूझने के बाद, मैं 3.9.1 पर वापस आ गया हूं। मुझे लगता है कि प्रमुख संस्करण बैककॉम को तोड़ सकते हैं / तोड़ सकते हैं लेकिन गुप्त और बेकार त्रुटि संदेशों के साथ, मैं कहता हूं कि कोई धन्यवाद नहीं। v4 तैयार नहीं है।
सत थिरू

जवाबों:


121

यह अभी तक एक आधिकारिक रिलीज़ नहीं है, लेकिन आने वाला गुल 4.0 आपको आसानी से gulp.series के साथ सिंक्रोनस कार्य करने देता है। आप बस इसे इस तरह से कर सकते हैं:

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

मुझे एक अच्छी ब्लॉग पोस्ट मिली जो उन स्वच्छ सुविधाओं का उन्नयन और उपयोग करने का तरीका प्रस्तुत करती है: उदाहरण के लिए gulp 4 में माइग्रेट करना


3
सभी नवागंतुकों के लिए पसंद की विधि। उन्हें वास्तव में गुल 4 से शुरू करना चाहिए, सभी को छोड़कर 3. * झंझट और विस्तृत एंटीपैटर्न की रेंज।
21

187
इसका 2017 और उन्होंने अभी भी इसे पेश नहीं किया है। महान।
टॉमाज़ मूलारस्क

14
मैं वास्तव में बात नहीं देखता। यदि आपको B रन के बाद केवल A को चलाने की आवश्यकता है, तो A, B पर निर्भर करता है। आप केवल यह निर्दिष्ट क्यों नहीं कर सकते कि B A की निर्भरता है? gulp.task('coffee', ['clean'], function(){...}); gulp.task('develop', ['coffee']);
म्यूज़िन

3
@ musicin3d आप जो कहते हैं वह काम करता है, लेकिन आप एक कार्य को पहले से जरूरी कर रहे हैं। उदाहरण के लिए, मैं चाहता हूं कि मैं पहले कभी भी लिंट किए बिना निर्माण कर सकूं। स्वतंत्र कार्यों के लिए और बाहरी उपकरण के साथ निष्पादन का क्रम तय करना बेहतर उपाय है।
एक्सफ़ेक्ट

11
इसका 2018 और उन्होंने अंत में इसे पेश किया। महान।
dargmuesli

411

जब तक उनके पास स्पष्ट निर्भरता न हो, डिफ़ॉल्ट रूप से, गल्प एक साथ कार्य करता है। यह उन कार्यों के लिए बहुत उपयोगी नहीं है clean, जैसे कि आप पर निर्भर नहीं रहना चाहते हैं, लेकिन आपको उन्हें सब कुछ से पहले चलाने की आवश्यकता है।

मैंने इस समस्या को ठीक करने के लिए विशेष रूप से प्लग इन लिखा हैrun-sequence । इसे स्थापित करने के बाद, इसे इस तरह उपयोग करें:

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

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

आप पैकेज README पर पूर्ण निर्देश पढ़ सकते हैं - यह एक साथ कुछ कार्यों को चलाने का समर्थन भी करता है।

कृपया ध्यान दें, यह (प्रभावी रूप से) गुलाल के अगले प्रमुख रिलीज में तय किया जाएगा , क्योंकि वे पूरी तरह से स्वचालित निर्भरता आदेश को समाप्त कर रहे हैं, और run-sequenceआपको मैन्युअल रूप से चलाने के लिए अनुमति देने के लिए इसी तरह के उपकरण प्रदान कर रहे हैं कि आप कैसे चाहते हैं।

हालांकि, यह एक बड़ा ब्रेकिंग परिवर्तन है, इसलिए जब आप run-sequenceआज का उपयोग कर सकते हैं तो इंतजार करने का कोई कारण नहीं है।


2
प्लगइन के लिए @OverZealous धन्यवाद! Btw, gulp-cleanप्लगइन धारा 2 को लागू नहीं कर रहा था, इसलिए यह एक निर्भरता के रूप में चलाए जा रहे मुद्दे थे। यह रिलीज़ संस्करण 0.3.0 के रूप में तय किया गया है, मेरे सहकर्मी ने इसे बदलने के लिए एक पीआर प्रस्तुत किया है।
ज्ञातव्य

3
@Indolering अंतर्निहित कार्य निर्भरता कार्यक्षमता इस परिदृश्य को हल नहीं करती है। आश्रित कार्य हमेशा चलाए जा रहे हैं: वहाँ कोई रास्ता नहीं में बनाया गया है एक पंक्ति में दो कार्यों को चलाने के लिए कुछ समय की, लेकिन नहीं हर समय। run-sequenceगुलाल में लापता कार्यक्षमता का एक महत्वपूर्ण टुकड़ा हल करती है।
ज्यादा

2
इसके अलावा, कार्य निर्भरता एक पूर्ण समाधान नहीं है। मान लें कि मेरे पास दो gulp कार्य हैं जो स्वतंत्र रूप से डेटाबेस का उपयोग करके परीक्षण चलाते हैं। न तो दूसरे पर निर्भर है, लेकिन मैं नहीं चाहता कि उनमें से कोई एक ही समय पर चले क्योंकि उन्हें दोनों को डेटाबेस का उपयोग करने की आवश्यकता है।
पीटरजीन

3
अद्भुत मॉड्यूल - यह क्यों की जरूरत है की एक महान विवरण - blog.mdnbar.com/gulp-for-simple-build-proccess- यह स्वीकृत उत्तर होना चाहिए
danday74

5
मैं आभारी हूं कि आपने इसके लिए एक समाधान किया, लेकिन यह बेतुका है कि हमें अनुक्रमिक निष्पादन प्राप्त करने के लिए अतिरिक्त टूलिंग की आवश्यकता है। अनुक्रमिक निष्पादन डिफ़ॉल्ट होना चाहिए, या कम से कम कमबख्त करना आसान होना चाहिए। 40 साल से मेकफाइल्स का अनुक्रमिक निष्पादन हुआ है। जेएस इकोसिस्टम मुझे बीमार बनाता है। 73 मेगाबाइट्स के नोड_मॉड्यूल केवल एक बॉयलरप्लेट प्रोजेक्ट को बिना किसी विशेषता के संकलित करने के लिए, और इसमें अभी भी अनुक्रमिक निष्पादन की क्षमता शामिल नहीं है। ऑपरेटिंग सिस्टम एक छोटी सी जगह में फिट होते हैं और इनमें कर्नेल और ड्राइवर 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कार्य पर चलाने की कोशिश कर रहा हूं , क्या मुझे कुछ याद आ रहा है?
वफ़ल

11
@ इस उदाहरण से कॉलबैक का उपयोग होता है, जो ऐसा करने का एकमात्र तरीका नहीं है। डॉक्स के अनुसार , आप "एक वादा या धारा वापस कर सकते हैं जो इंजन को क्रमशः हल करने या समाप्त होने का इंतजार करना चाहिए।" इसलिए यदि आप कार्य एक में एक धारा लौटाते हैं, जैसे return gulp.src('app/**/*.js').pipe(concat(app.js)).pipe(gulp.dest('app/scripts');, कार्य दो को परिभाषित करते समय कार्य को एक आश्रित के रूप में पहचानना है: gulp.task('two', ['one'], function() {... कार्य दो अब चलने से पहले कार्य के समाप्त होने की प्रतीक्षा करेंगे।
एवेन्यूसैन

24
इससे 'एक' और 'दो' के बीच एक तंग युग्मन बनता है। यदि आप 'दो' चलाना चाहते हैं तो क्या करें
विल्क

5
आप निर्भरता के बिना एक नया कार्य परिभाषित करते हैं?
मैथ्यू बॉर्डर

8
क्रमिक रूप से चलाने के लिए दो कार्यों की आवश्यकता है, एक तंग युग्मन।
रिंगो

56

मैं का उपयोग कर एक नोड / gulp एप्लिकेशन उत्पन्न किया जनरेटर-गुलप-वेबप योमन जनरेटर । इसने इस तरह से "स्वच्छ कोन्ड्रम" को संभाला (प्रश्न में उल्लिखित मूल कार्यों का अनुवाद):

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

2
यह सटीक (और बहुत सरल) मेरी जरूरत थी। यह उन परिदृश्यों को संबोधित करता है जहां मुझे उन कार्यों के लिए एक निर्भरता के रूप में स्वच्छ स्थापित किए बिना निर्भरता का निर्माण करने के लिए पूर्ववर्ती निर्भरता के रूप में एक स्वच्छ जैसा कुछ करने की आवश्यकता है। PS: gulp.start () बिट - कैविट एम्प्टर के बारे में जानकारी: github.com/gulpjs/gulp/issues/426
Jaans

यह समझ आता है; मुख्य कार्य (और यह निर्भर कार्यों है) के बाद एक कॉलबैक पूरा हो गया है। धन्यवाद।
markau

4
अगर कोई सोच रहा है कि कोई आधिकारिक दस्तावेज क्यों नहीं है gulp.start(), तो gulp के सदस्य का यह उत्तर बताता है कि: 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 )
थिसज़ी

1
इस मामले में, मैं उस coffeeकार्य का पता कैसे लगा सकता हूं ? अगर मैं इसका पता नहीं लगाता हूं, तो developटास्क इससे पहले खत्म हो जाएगाcoffee
थिब्जी

पहले ही run-sequenceस्रोत कोड से जवाब मिल गया gulp.on('task_stop'):। विवरण के लिए मेरा विस्तारित जवाब देखें: stackoverflow.com/a/38818657/3027390
21

32

रन-सीक्वेंस सबसे स्पष्ट तरीका है (कम से कम जब तक गुल 4.0 जारी नहीं होता है)

रन-सीक्वेंस के साथ , आपका काम इस तरह दिखेगा:

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.start इस उद्देश्य पर यह अनिर्दिष्ट है क्योंकि इससे जटिल बिल्ड फाइलें बन सकती हैं और हम नहीं चाहते कि लोग इसका उपयोग करें

(स्रोत: https://github.com/gulpjs/gulp/issues/426#issuecomment-41208007 )


इस आदमी को दो कॉफ़ी! श्रोता को हटाने के साथ समाधान पूरी तरह से काम करता है!
daniel.bavrin

यह वास्तव में जवाब है, या बस, "गुल 4"। रन क्रम मजबूत है।
LAdams87

26

गुल्फ डॉक्स के अनुसार:

क्या आपके कार्य निर्भरता पूर्ण होने से पहले चल रहे हैं? सुनिश्चित करें कि आपके आश्रित कार्य सही ढंग से एसिंक्स रन संकेत का उपयोग कर रहे हैं: कॉलबैक में लें या एक वादा या ईवेंट स्ट्रीम वापस करें।

अपने कार्यों को समकालिक रूप से चलाने के लिए:

  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
यह सही उत्तर होना चाहिए! रिटर्निंग टास्क ने किया टोटका! धन्यवाद दोस्त।
द्ज़ुक्र

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"

लौटने पर नोट के लिए धन्यवाद! क्या नट यह पता लगाने की कोशिश कर रहा था कि गुलदस्ता किस क्रम से काम कर रहा था।
एंड्रयू एफ

कार्यों के बीच तंग युग्मन से बचने के लिए यह सही उत्तर होना चाहिए। अच्छा काम करता है। 4.0 में उपलब्ध gulp.series शायद सबसे अच्छा जवाब है, लेकिन आज तक, 4.0 उपलब्ध नहीं है।
विल्क

Gulp पहले साफ या कॉफी चलेंगे विकसित
स्केप

8

सभी प्रस्तावित समाधानों की कोशिश की, सभी को अपने स्वयं के मुद्दे लगते हैं।

यदि आप वास्तव में ऑर्केस्ट्रेटर स्रोत .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(){...})

गुलप काफी स्मार्ट है cleanएक बार ठीक से चलाने के लिए build, चाहे कितनी भी buildनिर्भरता हो clean। जैसा कि ऊपर लिखा गया है, cleanएक सिंक्रनाइज़ेशन बाधा है, तो सभी की buildनिर्भरता समानांतर में चलती है, फिर buildचलती है।


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

गुल्प और नोड्स वादों का उपयोग करते हैं

तो आप यह कर सकते हैं:

// ... 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()कॉलबैक जोड़ने के लिए विधि का उपयोग कर सकते हैं । वैकल्पिक रूप से, आप Promiseअपने स्वयं के वादे बनाने के लिए नोड के मूल का उपयोग कर सकते हैं । यहां मैं Promise.all()एक कॉलबैक का उपयोग करता हूं जो सभी वादों को हल करने पर आग लगाता है।


-8

इस हैक की कोशिश करें :-) Async बग के लिए गुल v3.x हैक

मैंने रीडमी में सभी "आधिकारिक" तरीकों की कोशिश की, उन्होंने मेरे लिए काम नहीं किया लेकिन यह किया। आप 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

पोस्ट देखें!


समस्या को हल करने के लिए बेहतर तरीके हैं, सेटटाइमआउट का उपयोग करना उचित नहीं है। आप ठीक से नहीं जान सकते कि किसी कार्य को पूरा करने में कितना समय लगेगा।
रेगिनाल्डो केमारगो रिबेरो

आपको वास्तव में किसी भी कोड pff
DDD
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.