0

A simplified version of my gulp file looks like this:

stylusFiles=[...];

gulp.task("stylus", function(done){
  global.stopOnError = true;
  stylusFiles.forEach((file) => {
    executeStylus(file.name, file.src, Date.now());
  });
  done();
});

javascFiles = [firstjs, secondjs];

gulp.task("firstcompile", function (done) {
  createBundle(firstjs);
  done();
});

gulp.task("secondcompile", function (done) {
  createBundle(secondjs);
  done();
});

gulp.task("compile", function(done) {
  setVersion();
  global.stopOnError = true;
  stylusFiles.forEach((file) => {
    executeStylus(file.name, file.src, Date.now());
  });

  createBundles(javascFiles);
  done();
});

gulp.task("seqcompile",
  gulp.parallel("stylus",
  gulp.series("firstcompile","secondcompile"), 
  function(done) {
    setVersion();
    global.stopOnError = true;
    done();
  }
));

Stylus compilation works in concurrent manner (output order != order of stylus files in code). If I run gulp on any single JS file, it works. The reason I try to force sequential execution is that gulp compile on the full set of JS files either crashes with an "out of heap memory" error (even using --max_old_stack_size=12000 on a 16 GB workstation) or runs indefinitely (>10 h) on the larger JS files (original size <=24 MB). However, the way it is written here in the example, gulp seqcompile is still not sequential, since output order != order of JS files in code, and on my remote instance, gulp still runs indefinitely (at least I have now had success on the 16 GB workstation).

  1. How do I force sequential execution?
  2. It would be nice to be able to write something like gulp.series(javascFiles).
  3. I am not sure if setVersion is run only once before both stylus and js compilation, as it should.
  • Try replacing the `forEach` calls with `for...of` and see if you get sequential execution. – Mark Dec 10 '19 at 09:46
  • I will try that as soon as I have time! – Matthias Gralle Dec 10 '19 at 19:09
  • As a test, I tried it out with the stylus files: `for (const file of stylusFiles) {...};`, but the order of completion of the stylus builds is still different from the order that they are specified in the array stylusFiles, so execution is still concurrent. – Matthias Gralle Dec 16 '19 at 15:46
  • As nobody has been able to suggest to me a solution, I think I will have to abandon gulp in the near future for webpack or some other solution. – Matthias Gralle Dec 16 '19 at 15:47

1 Answers1

1

How do I force sequential execution?

Well you can try and force it with using an external package. Since you didn't mention what type of packages you are using, I'll just assume that you are not using gulp-sequence . Which is available here.

This package directly allows you to write gulp.task('sequence-1', gulpSequence(['a', 'b'], 'c', ['d', 'e'], 'f')) which can run tasks sequentially.

Another thing you can try is use the command gulp.series. A better explanation can be found here in this Stack Overflow answer.

would be nice to be able to write something like gulp.series(javascFiles).

Well for this exactly, please refer to my previous point. It was already described in a previous SO question.

I am not sure if setVersion is run only once before both stylus and js compilation, as it should.

A gulp task that will only run once usually indicates that gulp is unable to determine that it has finished the first time and so gulp will not run it again.

Another thing you can use for solving this, is this "gulp-once" package which only pass through files once unless changed.

I hope this helps.

ZombieChowder
  • 1,187
  • 12
  • 36
  • I am already using gulp.series, as you can see in the code above! – Matthias Gralle Dec 15 '19 at 15:07
  • @MatthiasGralle yes but have you checked the other packages I mentioned ? – ZombieChowder Dec 16 '19 at 20:38
  • gulp.series was introduced in gulp 4 to make fixes like gulp-sequence unnecessary. Nevertheless, since I really want to make this work, I gave gulp-sequence a try. It still runs concurrently and not in the order specified. `const runSequence = require('gulp4-run-sequence'); gulp.task("seqcompile2", function(done) { setVersion(); global.stopOnError = true; runSequence("production", "stylus","firstcompile","secondcompile", done ); });` – Matthias Gralle Dec 17 '19 at 13:52
  • I don't see the relevance of gulp-once for my question. – Matthias Gralle Dec 17 '19 at 13:56
  • Finally, I get the impression that gulp won't do what I want it to do unless (perhaps!) I completely rewrite my gulp file, and in that case I prefer to migrate to something like webpack. – Matthias Gralle Dec 17 '19 at 13:57