63

I am aware of the ability to declare dependencies that will run before the task, e.g.

gulp.task('a', () => {});
gulp.task('b', () => {});
gulp.task('c', ['a', 'c'], () => {});

Tasks 'a' and 'b' will be run every time after task 'c' is called and before task 'c' is executed.

However, how do I programmatically call an arbitrary task from within a gulp.task?

Gajus
  • 69,002
  • 70
  • 275
  • 438

7 Answers7

74

I did it using gulp.start(); like this:

gulp.task('test1', function(){
  gulp.start('test2');
})

gulp.task('test2', function(){
  // do something
})

I was using gulp 3.9.1 if it matters. Looks like gulp.start() may be removed or deprecated; but it hasn't happened yet.


Update If I were to break things out into separate functions, as Novellizator suggested, it would be something like this:

function doSomething(){
  // do something
}

gulp.task('test1', function(){
  doSomething();
})

gulp.task('test2', function(){
  doSomething();
})

It is simple and avoids the use of gulp.start().

JeffryHouser
  • 39,401
  • 4
  • 38
  • 59
26

From Gulp 4+ I found this to work well as a replacement for gulp.start:

const task1 = () => { /*do stuff*/ };
const task2 = () => { /*do stuff*/ };

// Register the tasks with gulp. They will be named the same as their function
gulp.task(task1);
gulp.task(task2);

...

// Elsewhere in your gulfile you can run these tasks immediately by calling them like this
(gulp.series("task1", "task2")());
// OR
(gulp.parallel("task1", "task2")());
DoubleA
  • 1,636
  • 14
  • 28
7

On the general theme of "don't" from the other answers, it depends what you're doing.

If you're thinking:

gulp.task("a", () => {
    doSomethingInstant()
    return doTaskB()
})

You want:

gulp.task("meta-a", () => {
    doSomethingInstant()
})
gulp.task("a", ["meta-a", "b"])

This works because all the tasks are started in order, so if you're not doing anything async in "meta-a", it will finish before "b" starts. If it's async then you need to be much more explicit:

gulp.task("meta-a", () => {
    return doSomethingAsync()
})
function taskB() {
    // Original task B code...
}
gulp.task("b", taskB)
gulp.task("a", ["meta-a"], taskB)
Jim Driscoll
  • 894
  • 11
  • 8
7

On a related note, you can initiate the tasks using either gulp.series or gulp.parallel in gulp v4. Although it's not a direct replacement for gulp.start, it achieves the same objective.

Example:

Before v4

gulp.task('protractor', ['protractor:src']);

After v4

gulp.task('protractor', gulp.series('protractor:src'));
John Lee
  • 893
  • 13
  • 14
3

As JeffryHouser stated above using the following method works but is deprecated and will be removed in future versions. I just attempted the following on 3.9.1 and it works fine.

Code:

// Variables
var gulp = require('gulp');
var less = require('gulp-less');
var watch = require('gulp-watch');


// Task to compile less -> css: Method 1- The bad way
gulp.task('default', function(){
    gulp.src('src/*.less')
    gulp.start('lessToCss');
});

gulp.task('lessToCss', function() {
    gulp.src('src/*.less')
    .pipe(less())
    .pipe(gulp.dest('src/main.css'));
});

The second way mentioned in the comment by Novellizator is:

"Break tasks out into functions, then reuse them in other tasks if you need to" piece of advice from the aforementioned issue

I do this by use of lazypipe() https://www.npmjs.com/package/lazypipe

Code:

// Variables
var gulp = require('gulp');
var less = require('gulp-less');
var watch = require('gulp-watch');

var lazypipe = require('lazypipe');
var fixMyCSS = lazypipe()
     .pipe(less); // Be CAREFUL here do not use less() it will give you an errror



// Task to compile less -> css: Method 2 - The nice way
gulp.task('default', function(){
    //gulp.start('lessToCss');
    gulp.src('src/*.less')
    .pipe(fixMyCSS())
    .pipe(gulp.dest('src/main.css'));
});

A brief comparison

Method 1 yielding the following:

  • Starting 'default'...
  • [22:59:12] Starting 'lessToCss'...
  • [22:59:12] Finished 'lessToCss' after 13 ms
  • [22:59:12] Finished 'default' after 48 ms

For a total of 61 ms to complete

Method 2? - [23:03:24] Starting 'default'... - [23:03:24] Finished 'default' after 38 ms

Practically half that at 38 ms

For a total difference of 23 ms

Now why this is the case? I honestly don't know enough about gulp to say, but let's say method 2 is clearly the more readable,maintainable and even the faster choice.

They are both easy to write so long as you understand not to call a stream directly within the lazypipe().

Callat
  • 2,928
  • 5
  • 30
  • 47
  • 1
    That is a more complex interpretation of @Novellizator's comment than my interpertation. I modified my answer to include an alternate approach. It is tough to evaluate the performance stats in isolation, especially since you're running different code. If lessToCss uses an incremental approach it is expected the second run would be quicker than the first. – JeffryHouser Oct 06 '17 at 13:52
  • 1
    .start is deprecated – Jonathan May 27 '19 at 22:36
-2

The best way form me is:

task('task1', () => {
  // Buy potatoes
});

task('task2', ['task1'], () => {
  // Cut potatoes
});

The result of the task2 it will be: Buy potatoes and Cut potatoes

Sebastian Diez
  • 172
  • 1
  • 4
-6

There are a couple of ways to do this: The first one: just invoke a new task call for the other:

gulp.task('foo', function() {
  gulp.task('caller', ['bar']); // <- this calls the other existing task!
}
gulp.task('bar', function() {
  //do something
}

The second, less cleaner one: Gulp is Javascript, so you just set a couple of instructions as a random function and call it!

gulp.task('task', function() {
  recurrent_task();
}
gulp.task('task2', function() {
  recurrent_task();
}
function recurrent_task() {
  //do something
}
PpToño
  • 1
  • 3
  • 1
    The first suggestion just registers a gulp task but without a callback function, so yeah, it won't work. – joeycozza May 19 '17 at 17:37