30

I am trying to merge css and scss files into a main.css file that goes in my build directory. Its working, but not in the right order. The style attributes from the scss files need to be in the bottom of the main.css file so they overrule the rest.

my Gulp task looks like this:

    //CSS
gulp.task('css', function () {
    var cssTomincss = gulp.src(['dev/css/reset.css', 'dev/css/style.css','dev/css/typography.css',    'dev/css/sizes.css']);

    var cssFromscss = gulp.src(['dev/css/*.scss'])
        .pipe(sass());

    return es.merge(cssTomincss, cssFromscss)
        .pipe(concat('main.css'))
        .pipe(minifyCSS())
        .pipe(gulp.dest('build/css'))
});

I am defining the sources first with variables. I am using the gulp-sass plugin to convert the scss file into normal css (.pipe(sass)) and later merging the two with the es.merge function and concatenating them into main.css.

The problem is that the style attributes van the .scss files end up somewhere in the top end of the main.css file. I need them to be at the bottom. So they need to be concatenated at the bottom.

Any clue on how to do this?

Balthazar
  • 33,765
  • 10
  • 77
  • 104
Jabba Da Hoot
  • 796
  • 2
  • 6
  • 15

4 Answers4

56

Try streamqueue.

var streamqueue = require('streamqueue');

gulp.task('css', function () {
    return streamqueue({ objectMode: true },
            gulp.src(['dev/css/reset.css', 'dev/css/style.css', 'dev/css/typography.css', 'dev/css/sizes.css']),
            gulp.src(['dev/css/*.scss']).pipe(sass())
        )
        .pipe(concat('main.css'))
        .pipe(minifyCSS())
        .pipe(gulp.dest('build/css'))
});

This cheatsheet will help you. PDF is here.

Tsutomu Kawamura
  • 1,081
  • 9
  • 10
  • 2
    Ok, that was epic. It worked! Looked into it and I understand it now. Thanks a ton!! – Jabba Da Hoot Sep 29 '14 at 16:31
  • Hi! I'm using streamqueue thanks to you.. but running into issues :( mind a look? http://stackoverflow.com/questions/28522916/how-to-order-the-compiling-of-javascript-files-in-gulp – Leon Gaban Feb 15 '15 at 04:16
  • streamqueue always throws "Cannot switch to old mode now". Using merge-stream and then gulp-order works though. – user764754 Sep 20 '16 at 15:18
  • It doesn't concat them in the right order :( Even if I invert the order in streamqueue, it still outputs the same (wrong) way. How does that even... ? – Carles Alcolea Jan 28 '17 at 20:45
5

It seems that the plugin gulp-order fits perfectly well in your case.

It allows you to re-order the passed stream with your own glob pattern, for example based on your code :

return es.merge(cssTomincss, cssFromscss)
    .pipe(order([
      'dev/css/reset.css',
      'dev/css/style.css',
      'dev/css/typography.css',
      'dev/css/sizes.css',
      'dev/css/*.css',
    ]))
    .pipe(concat('main.css'))
    .pipe(minifyCSS())
    .pipe(gulp.dest('build/css'))

One drawback of this is that you have to re-declare your globs, but you can get around by assign your globs to a value and then concat them in you order pipe, much cleaner.

You may have to set the base option to . of gulp-order as stated in their Readme if the files were not ordered correctly.

One another way would be to use stream-series, basically the same as event-stream, but the order of your stream is preserved, and you don't have to rewrite your globs.

Balthazar
  • 33,765
  • 10
  • 77
  • 104
  • sometimes it didn't pickup paths as expected. Using `.pipe(order[path1, path2], { base: '.' })` solved it. – Valerio Mar 24 '15 at 00:41
  • 1
    Hum, were the files in different folders? Will add this info in my answer, thanks. – Balthazar Mar 24 '15 at 10:03
  • Great answer - just a reminder to people following this answer that you need to install gulp-order via npm and import it at the top of your gulp file. – rhysclay Oct 26 '16 at 22:48
5

I tried gulp-order without success: the order somehow wasn't taken into account.

The solution which worked for me was using stream-series, mentioned by Aperçu.

return streamSeries(
    cssTomincss,
    cssFromscss)
    .pipe(concat('main.css'))
    .pipe(minifyCSS())
    .pipe(gulp.dest('build/css'));
Community
  • 1
  • 1
Blackbird
  • 2,288
  • 4
  • 23
  • 39
1

I failed with all provided answers, they produced some silent errors. Finally merge2 worked for me (seems like there was gulp-merge and later the project was renamed into merge2). I'm not sure why there is a need in streamify plugin, e.g. streams created with Rollup may produce "stream-not-supported-errors" with gulp-concat, gulp-uglify or gulp-insert.

const mergeStreams = require('merge2');
const streamify = require('streamify');
...
gulp.task('build', () => {
    const streams = sources.map(createJSFile);
    return mergeStreams(...streams)
        .pipe(streamify(concat('bundle.js')))
        .pipe(streamify(uglify()))
        .pipe(gulp.dest('./dist'));
});
Alexander Shutau
  • 2,234
  • 18
  • 31