60

I currently have two tasks, that both compile sass files. I would still like to concat the two directories into separate files but it seems that it would be more maintainable if I could simply create a 'sass' task that would be responsible for all of the sass compilation.

// Compile Our Sass
gulp.task('bootstrap-sass', function() {
  return gulp.src('./public/bower/bootstrap-sass/lib/*.scss')
    .pipe(sass())
    .pipe(contcat('bootstrap.css'))
    .pipe(gulp.dest('./public/dist/css'));
});

gulp.task('site-sass', function() {
  return gulp.src('./public/app/scss/*.scss')
    .pipe(sass())
    .pipe(contcat('site.css'))
    .pipe(gulp.dest('./public/dist/css'));
});

UPDATE:

I've tried this:

// Compile Our Sass
gulp.task('sass', function() {
  var bootstrap = function() {
    return gulp
      .src('./public/bower/bootstrap-sass/lib/*.scss')
      .pipe(sass())
      .pipe(concat('bootstrap.css'))
      .pipe(gulp.dest('./public/dist/css'));
  };

  var site = function() {
    return gulp
      .src('./public/src/scss/*.scss')
      .pipe(sass())
      .pipe(concat('site.css'))
      .pipe(gulp.dest('./public/dist/css'));
  };

  return Promise.all([bootstrap, site]);
});

But now it appears that neither file is being compiled. Any suggestions on what I am doing wrong?

ZachB
  • 13,051
  • 4
  • 61
  • 89
Noah Goodrich
  • 24,875
  • 14
  • 66
  • 96

11 Answers11

69

I think the proper way of doing this is using task dependency.

In gulp you can define tasks that needs to be run before a given task.

For instance:

gulp.task('scripts', ['clean'], function () {
    // gulp.src( ...
});

When doing gulp scripts in the Terminal, clean is run before the scripts task.

In your example I'd have the two seperate SASS tasks as a dependency of a common SASS task. Something like:

// Compile Our Sass
gulp.task('bootstrap-sass', function() {
  return gulp.src('./public/bower/bootstrap-sass/lib/*.scss')
    .pipe(sass())
    .pipe(contact('bootstrap.css'))
    .pipe(gulp.dest('./public/dist/css'));
});

gulp.task('site-sass', function() {
  return gulp.src('./public/app/scss/*.scss')
    .pipe(sass())
    .pipe(contact('site.css'))
    .pipe(gulp.dest('./public/dist/css'));
});

gulp.task('sass', ['bootstrap-sass', 'site-sass']);

You read more about the task dependecy on the Gulp recipes section: https://github.com/gulpjs/gulp/blob/master/docs/recipes/running-tasks-in-series.md

mikaelb
  • 2,158
  • 15
  • 15
  • 3
    To those stumbling upon this in 2019-ish: This does not work in Gulp 4. See other answers that use `parallel` and/or `series`. – ACJ Nov 26 '19 at 12:28
35

It works.

var task1 = gulp.src(...)...
var task2 = gulp.src(...)...
return [task1, task2];
Denis535
  • 3,407
  • 4
  • 25
  • 36
23

Solution 1:

gulp.task('sass', function() {
  gulp.start('bootstrap-sass', 'site-sass');
})

gulp.start runs tasks in parallel. And it's asynchronous, which means 'bootstrap-sass' may be finished before 'site-sass'. But it's not recommended because

gulp.start is undocumented on purpose because it can lead to complicated build files and we don't want people using it

see https://github.com/gulpjs/gulp/issues/426

Solution 2:

var runSequence = require('run-sequence');
gulp.task('sass', function (cb) {
  runSequence(['bootstrap-sass', 'site-sass'], cb);
});

run-sequence is a gulp plugin.

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.

runSequence(['bootstrap-sass', 'site-sass'], cb);

This line runs 'boostrap-sass' and 'site-sass' in parallel.If you want to run tasks serially, you can

runSequence('bootstrap-sass', 'site-sass', cb);
ebpa
  • 1,171
  • 1
  • 12
  • 31
gzc
  • 8,180
  • 8
  • 42
  • 62
  • Could you explain your answer please? code-only answers are usually not accepted because they don't necessarily help others to understand how to solve a problem by themselves in future. – Wai Ha Lee May 12 '15 at 11:01
  • "Recommended" is such a misused world in the post-windows-xp era – Ярослав Рахматуллин Aug 14 '17 at 17:13
  • @ЯрославРахматуллин Could you explain it? – gzc Aug 15 '17 at 05:23
  • It is a subjective remark; "recommended" is sometimes used to refer to the idiot-safe choice. I am offended by that. Other times it is used to point to a choice that is beneficial to the one asking the question (as opposed to whom it is recommended) - e.g. install some malware (recommended) in an installation wizard. In this answer, it is the idiot-safe choice. It is completely irrelevant for two independant tasks, the recommendation is useless for any other case that the very specific saas1, then sass2 use case. Imho it's better to understand stuff than to follow recommendations – Ярослав Рахматуллин Aug 15 '17 at 08:07
  • @ЯрославРахматуллин I use "recommended" to refer to advice or suggestion. Have added some explanations why it's not recommended. – gzc Aug 18 '17 at 11:37
18

With Gulp4 you can use:

  • gulp.series for sequential execution
  • gulp.parallel for parallel execution

    gulp.task('default', gulp.series('MyTask001', 'MyTask002'));
    gulp.task('default', gulp.parallel('MyTask001', 'MyTask002'));

Article about here
You dont need run-sequence plugin anymore
You need install: npm install -D gulp@next

Mark
  • 247
  • 1
  • 4
  • 11
6

In Gulp version 4, we have parallel, so you can do:

// Compile Our Sass
gulp.task('bootstrap-sass', function() {
  return gulp.src('./public/bower/bootstrap-sass/lib/*.scss')
    .pipe(sass())
    .pipe(concat('bootstrap.css'))
    .pipe(gulp.dest('./public/dist/css'));
});

gulp.task('site-sass', function() {
  return gulp.src('./public/app/scss/*.scss')
    .pipe(sass())
    .pipe(concat('site.css'))
    .pipe(gulp.dest('./public/dist/css'));
});

gulp.task('sass', gulp.parallel('bootstrap-sass', 'site-sass')); // Combine

You can also write it as a single task by doing:

gulp.task('sass', gulp.parallel(
  function() {
      return gulp.src('./public/bower/bootstrap-sass/lib/*.scss')
        .pipe(sass())
        .pipe(concat('bootstrap.css'))
        .pipe(gulp.dest('./public/dist/css'));
  },
  function() {
      return gulp.src('./public/app/scss/*.scss')
        .pipe(sass())
        .pipe(concat('site.css'))
        .pipe(gulp.dest('./public/dist/css'));
  }));

I prefer the first method because it is easier to maintain

smac89
  • 39,374
  • 15
  • 132
  • 179
5

I just found a gulp plugin called gulp-all and tried it. It's simple to use.

https://www.npmjs.com/package/gulp-all

The documentation of the package says:

var all = require('gulp-all')

var styl_dir = 'path/to/styles/dir'
var js_dir   = 'path/to/scripts/dir'

function build() {
    return all(
        gulp.src(styl_dir + '/**/*')
            // build Styles 
            .pipe(gulp.dest('dist_dir')),
        gulp.src(js_dir + '/**/*')
            // build Scripts 
            .pipe(gulp.dest('dist_dir'))
    )
}

gulp.task('build', build);

also you can put subtasks in an array:

var scriptBundles = [/*...*/]

function build(){
    var subtasks = scriptBundles.map(function(bundle){
        return gulp.src(bundle.src).pipe(/* concat to bundle.target */)
    })
    return all(subtasks)
}
Louis
  • 146,715
  • 28
  • 274
  • 320
user5509760
  • 51
  • 1
  • 1
  • 3
    I've edited your answer to quote what you've copied from the package's documentation. You definitely should also add a warning to your answer (just like the package itself does) that it works only with Gulp 4, which has not been released yet. – Louis Oct 31 '15 at 13:09
3

I'm not sure if I understand question correctly, but if I do, this should be a simple solution:

gulp.task('sass', ['bootstrap-sass', 'site-sass']);
Tahi Reu
  • 558
  • 1
  • 8
  • 19
2

Turns out that the site() function was returning an error. In order to fix it, I needed to make sure bootstrap() ran first so I ended up with this:

// Compile Our Sass
gulp.task('sass', function() {
  var bootstrap = function() {
    return gulp
      .src('./public/bower/bootstrap-sass/lib/*.scss')
      .pipe(sass())
      .pipe(concat('bootstrap.css'))
      .pipe(gulp.dest('./public/dist/css'));
  };

  var site = function() {
    return gulp
      .src('./public/src/scss/*.scss')
      .pipe(sass())
      .pipe(concat('site.css'))
      .pipe(gulp.dest('./public/dist/css'));
  };

  return bootstrap().on('end', site);
});
Noah Goodrich
  • 24,875
  • 14
  • 66
  • 96
  • 2
    I would really recommend solving this with tasks dependencies instead of this. Not only is it the prefered solution, but it's essentially the same thing you are doing - only you are doing it manually and much less descriptive if you ask me. Also if you really prefer to combine streams, you can look into "stream-combiner". Here is an example you can look at: https://github.com/gulpjs/gulp/blob/master/docs/recipes/combining-streams-to-handle-errors.md#combining-streams-to-handle-errors – mikaelb Jun 16 '14 at 08:40
1

Have you tried using merge-stream?

merge = require('merge-stream');
// Compile Our Sass
gulp.task('sass', function() {
  var bootstrap = gulp
      .src('./public/bower/bootstrap-sass/lib/*.scss')
      .pipe(sass())
      .pipe(concat('bootstrap.css'))
      .pipe(gulp.dest('./public/dist/css'));

  var site = gulp
      .src('./public/src/scss/*.scss')
      .pipe(sass())
      .pipe(concat('site.css'))
      .pipe(gulp.dest('./public/dist/css'));

  return merge(bootstrap, site);

});

See https://blog.mariusschulz.com/2015/05/02/merging-two-gulp-streams for more details

I-Lin Kuo
  • 3,220
  • 2
  • 18
  • 25
1

THE SOLUTION: call the functions!!!

return Promise.all([bootstrap(), site()])

Be aware of the parens bootstrap(), site() so they return a promise :)

nicoabie
  • 2,684
  • 1
  • 20
  • 19
0

Its also possible, to create another task to compile other tasks by passing an array of task names like this:

gulp.task('sass-file-one', function () {
     console.log('compiled sass-file-one')
});
gulp.task('sass-file-two', function () {
     console.log('compiled sass-file-two')
});

gulp.task('compile-all-sass', ['sass-file-one','sass-file-two']);

then you can simply run gulp compile-all-sass

Angie
  • 140
  • 1
  • 8