20

I try to DRY my gulpfile. There I have small duplication of code I not comfortable with. How can this be made better?

gulp.task('scripts', function() {
  return gulp.src('src/scripts/**/*.coffee')
    .pipe(coffeelint())
    .pipe(coffeelint.reporter())
    .pipe(coffee())
    .pipe(gulp.dest('dist/scripts/'))
    .pipe(gulp.src('src/index.html'))  // this
    .pipe(includeSource())             // needs
    .pipe(gulp.dest('dist/'))          // DRY
});

gulp.task('index', function() {
  return gulp.src('src/index.html')
    .pipe(includeSource())
    .pipe(gulp.dest('dist/'))
});

I got index as a separate task, since I need to watch src/index.html to livereload. But I'm also watching my .coffee sources and when they change, I need to update src/index.html as well.

How can I pipe to index in scripts?

JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
srigi
  • 1,682
  • 1
  • 15
  • 30
  • Possible duplicate of [How to run Gulp tasks synchronously/one after the other](http://stackoverflow.com/questions/22824546/how-to-run-gulp-tasks-synchronously-one-after-the-other) – falsarella Mar 15 '16 at 16:59

2 Answers2

25

gulp enables you to order a series of tasks based on arguments.

Example:

gulp.task('second', ['first'], function() {
   // this occurs after 'first' finishes
});

Try the following code, you will be running the task 'index' to run both tasks:

gulp.task('scripts', function() {
  return gulp.src('src/scripts/**/*.coffee')
    .pipe(coffeelint())
    .pipe(coffeelint.reporter())
    .pipe(coffee())
    .pipe(gulp.dest('dist/scripts/'));
});

gulp.task('index', ['scripts'], function() {
  return gulp.src('src/index.html')
    .pipe(includeSource())
    .pipe(gulp.dest('dist/'))
});

The task index will now require scripts to be finished before it runs the code inside it's function.

Konstantin Grushetsky
  • 1,012
  • 1
  • 15
  • 32
SteveLacy
  • 4,150
  • 2
  • 23
  • 30
  • I will try this approach as soon as I can. – srigi Jun 09 '14 at 15:50
  • 1
    and what if `scripts` will run, and there is a need to run `index` right after `scripts`? – vsync Jan 17 '16 at 15:00
  • 2
    I prefer to use `run-sequence` to orchestrate my tasks, so in general this solution is correct - separate repeating job into own gulp.task. – srigi Feb 25 '16 at 09:36
  • @vsync then you would make a task which calls index the same way index calls scripts. it will chain together very nicely so you can call just one task from the console. in this case 'gulp index' – Zanven Mar 17 '16 at 03:56
  • Save stream to disk to load it in another task? This pattern looks a lot more "grunty" than "gulpy". – Gerardo Lima Oct 14 '16 at 18:02
  • This 100% does not work. I get the following error `AssertionError: Task function must be specified` – Bjorn Dec 30 '16 at 04:38
  • As I understand and have tested, gulp just checks that `[index]` starts after `[scripts]`, not that `[scripts]` has finished gulping. So in the case: `gulp.task('2',['1'], function() { whatever() });` Gulp will run 1, and just after 1 has started it will run 2. Runsequence is better to fix this, or even a check if 1 has really finished and just then trigger 2. Or like @gerardo-lima said, little grunty way. – Billeeb Sep 12 '17 at 14:11
  • @Bjorn need to add gulp.series(['first']) instead ['first'] – Martino May 16 '23 at 11:23
3

If you look into the Orchestrator source, particularly the .start() implementation you will see that if the last parameter is a function it will treat it as a callback.

I wrote this snippet for my own tasks:

  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" ));
Assaf Moldavsky
  • 1,681
  • 1
  • 19
  • 30