How do I force gulp calls to run synchronously?
Asked Answered
N

6

17

I want the gulp calls below to run synchronously, one after the other. But they do not follow an order.

The run-sequence node module doesn't help here, as I'm not trying to run gulp tasks in series (i.e. it has syntax similar to gulp.task("mytask", ["foo", "bar", "baz"] etc.), but rather gulp "calls" in series, as you see below.

gulp.task("dostuff", function (callback) {

  gulp
    .src("...")
    .pipe(gulp.dest("...");

  gulp
    .src("...")
    .pipe(gulp.dest("...");

  gulp
    .src("...")
    .pipe(gulp.dest("...");

  callback();
});

How do I make them run one after the other?

Neubauer answered 13/12, 2014 at 14:32 Comment(7)
You don't want to run them in series, so parallel? But that contradict the fact that you want to run them synchronously... Your last sentence also state for what I would call a serie. Can you please choose what you want?Ohalloran
@Aperçu As the title says, synchronously. In series.Neubauer
"as I'm not trying to run tasks in series"Ohalloran
@Aperçu See edit above... I see why the confusion :)Neubauer
Thanks, that's better :) But in your example, gulp.task("mytask", ["foo", "bar", "baz"]), you know the tasks does not have any specific order, it's more a parallel.Ohalloran
@Apercu yes that plugin uses that sort of syntax to run in series or parallel. My point is I dont want that. I want to run gulp calls in series, not entire tasks.Neubauer
Okay I get it, sorry for the misunderstoodOhalloran
O
10

You can use async as a control flow for your calls to get them in only one task, also avoiding you to get a "pyramid effect". So something like this should be good for your use-case:

var async = require('async');

gulp.task('yeah', function (cb) {
  async.series([
    function (next) {
      gulp.src('...')
        .pipe(gulp.dest('...')
        .on('end', next);
    },
    function (next) {
      gulp.src('...')
        .pipe(gulp.dest('...')
        .on('end', next);
    },
    function (next) {
      gulp.src('...')
        .pipe(gulp.dest('...')
        .on('end', next);
    }
  ], cb);
});

That will also allow you to have some error handling and target better where a problem occured.

Ohalloran answered 13/12, 2014 at 20:28 Comment(2)
FYI - if ".on('end', next)" doesn't work, try ".on('finish', next)".Aftertaste
Have a scenario where I have to rely on variables built in the first promise. Using them just in the 2nd of a chain wasn't possible, but I had to put the second promise in then. Nevertheless the general approach helped.Kolivas
R
4

Well, it's just streams so you could listen for the end event (Watch out for the pyramid of doom!)

gulp.task("dostuff", function (callback) {

  gulp
    .src("...")
    .pipe(gulp.dest("..."))
    .on('end', function () {

      gulp
        .src("...")
        .pipe(gulp.dest("..."))
        .on('end', function () {

          gulp
            .src("...")
            .pipe(gulp.dest("..."))
            .on('end', callback);

        });
    });
});

But it's probably a better pattern to split it up in multiple tasks each one with a dependency on the previous one.

Rascally answered 13/12, 2014 at 20:6 Comment(5)
I need them all in one task. This code is useful if you already have them split into a number of tasks. My design doesn't work that way...Neubauer
Oops, misinterpreted your question. gulp.src() returns a stream so you can use the end event I guess. I updated the answerRascally
plusone Works, but the pyramid gets out of hand if you are composing all this dynamically at runtime. For that case, the accepted answer is better. But this works too for a simple case, as well as when you don't want to use an external library.Neubauer
By all means, control flow libraries are there to structure your async code, use them. Would you mind sharing your gulpfile? I'm pretty sure there's better ways to compose your streams so you don't have to run anything in series at all.Rascally
created dynamically, that's why the pyramid was no good for my use case. In a simple/static case I would choose your way as it's easier.Neubauer
D
2

run-sequence:

Runs a sequence of gulp tasks in the specified order. This function is designed to solve the situation where you have defined run-order, but choose not to or cannot use dependencies.

npm install --save-dev run-sequence

// runSequence will ensure this task will run the following tasks in the listed order
gulp.task('things-to-do', callback => runSequence(
    'clean-up-workspace', // clean up before copying new files
    'copy-new-files', // wait till copy-new-files done before linting
    'lint', // wait till lint is done before running minify
    'minify', // wait till minify is done before starting laundry and dinner
    ['do-laundry', // do laundry and cook dinner at the same time
    'cook-dinner'],
    'bath-cat', // don't bath the cat till both laundry and dinner are done
    callback
));

https://www.npmjs.com/package/run-sequence

Duumvir answered 28/4, 2017 at 15:31 Comment(0)
K
0

Use synchronous mode for glob

Then return the result of gulp.src:

gulp.task('render', function() {
    var appJsFiles = _.map(glob.sync('src/**/*.js'), function(f) {
        return f.slice(6);
    });
    // Render the file.
    return gulp.src('src/template.html')
        .pipe(template({
            scripts: appJsFiles,
            styles: ['style1.css', 'style2.css', 'style3.css']
        }))
        .pipe(gulp.dest(config.build_dir));
});
Kookaburra answered 13/12, 2014 at 14:42 Comment(2)
I don't understand. How does this run three gulp executions one after the other? I'm new to gulp so maybe the answer is obvious, but I don't see it...Neubauer
I don't think this answers the question asked, but is exactly what I came to this page from Google looking for. Loads a list of files via glob into an array before the gulp command is run, which the gulp plugins can then consume. Thanks!Teaspoon
L
0

you can add something like this after the last pipe

.pipe(gulp.dest(FINAL_DEST))
.on('end', () => gulp.src(['build']) .pipe(clean()))
Leafage answered 14/7, 2017 at 2:24 Comment(0)
F
0

It should work like this ....

gulp.src("...")
        .pipe(gulp.dest("..."))
        .on('end', () => {
            gulp.src("...")
                .pipe(gulp.dest("..."))
    
        })
        .on('end', () => {
            gulp.src("...")
                .pipe(gulp.dest("..."))
    
        })
        .on('end', () => {
            gulp.src("...")
                .pipe(gulp.dest("..."))
    
        })

but it doesn't .... instead it wors like this ....

gulp.src("...")
.pipe(gulp.dest("..."))
.on('end', () => {
    gulp.src("...")
        .pipe(gulp.dest("..."))
        .on('end', () => {
            gulp.src("...")
                .pipe(gulp.dest("..."))
                .on('end', () => {
                    gulp.src("...")
                        .pipe(gulp.dest("..."))
            
                })
    
        })
})

        
Fleece answered 13/1, 2022 at 18:52 Comment(1)
While this code snippet may solve the problem, it doesn't explain why or how it answers the question. Please include an explanation for your code, as that really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion.Alvinalvina

© 2022 - 2024 — McMap. All rights reserved.