3

I have a gulp file that I use and it contains a process that creates a standard non-compressed .css file and a compressed .css file; I used to generate the compressed version simply by minifying the just generated non-compressed one, however this caused issues with mappings pointing to the non-compressed .css file rather than the .scss files since it never actually worked off the .scss files.

So I changed it so that both processes now use the .scss files, however this seems very inefficient as they both have to go through the same processes so they can build their respective files.

Here is the relevant part of my gulpfile.js:

 var gulp = require('gulp');
 var cssnano = require('gulp-cssnano');
 var plumber = require('gulp-plumber');
 var postcss = require('gulp-postcss');
 var rename = require('gulp-rename');
 var sass = require('gulp-sass');
 var sourcemaps = require('gulp-sourcemaps');
 var uglify = require('gulp-uglify');
 var livereload = require('gulp-livereload');
 var autoprefixer = require('autoprefixer');

 var ap_options = {
     browsers: [
         'last 4 Chrome versions',
         'last 4 Firefox versions',
         'last 4 Edge versions',
         'last 2 Safari versions',
         'ie >= 10',
         '> 1.49%',
         'not ie <= 9'
     ],
 };

 gulp.task('postcss', function() {
     return gulp.src('scss/*.scss')
         .pipe(plumber()) // Deal with errors.
         .pipe(sourcemaps.init()) // Wrap tasks in a sourcemap.
         .pipe(sass({ // Compile Sass using LibSass.
             errLogToConsole: true,
             outputStyle: 'expanded' // Options: nested, expanded, compact, compressed
         }))
         .pipe(postcss([ // Parse with PostCSS plugins.
             autoprefixer(ap_options),
         ]))
         .pipe(sourcemaps.write('../maps')) // Create sourcemap.
         .pipe(gulp.dest('./css/')) // Create style.css.
         .pipe(livereload());
 });

 gulp.task('cssnano', ['postcss'], function() {
     return gulp.src('scss/*.scss')
         .pipe(plumber()) // Deal with errors.
         .pipe(sourcemaps.init()) // Wrap tasks in a sourcemap.
         .pipe(sass({ // Compile Sass using LibSass.
             errLogToConsole: true,
             outputStyle: 'compressed' // Options: nested, expanded, compact, compressed
         }))
         .pipe(postcss([ // Parse with PostCSS plugins.
             autoprefixer(ap_options),
         ]))
         .pipe(cssnano({ // Minify CSS
             safe: true // Use safe optimizations
         }))
         .pipe(rename({ suffix: '.min' })) // Append our suffix to the name
         .pipe(sourcemaps.write('../maps')) // Create sourcemap.
         .pipe(gulp.dest('./css/')) // Create style.min.css.
         .pipe(livereload());
 });

Is there a more efficient way to do this where I can create correct mapping files for both the non-compressed and compressed versions?

henry
  • 4,244
  • 2
  • 26
  • 37
Brett
  • 19,449
  • 54
  • 157
  • 290
  • How much longer does it take to build both CSS files from SCSS compared to building the min version from the uncompressed version? – Duderino9000 Sep 16 '16 at 03:52
  • @Barryman9000 Not real sure, I suppose I can do some tests. But the main issue is the PC I work on at work is a lot slower than my home PC and I'm trying to speed the process up as it's kinda slow. – Brett Sep 16 '16 at 19:57

1 Answers1

1

I found that gulp-cssnano was super slow so using gulp-clean-css can at least help speed things up. You can use gulp-if and a separate variables module to toggle some settings and call the same task twice. So it only calls rename and 'cssnano' if isProduction = true and liveReload if isProduction = false so you can use it with gulp-watch. I haven't tested this but it should work!

variables.js

module.export = {
    isProduction = false,
    outputStyle = 'expanded'
};

gulpfile.js

var vars = require('./variables'),
    runSequence = require('run-sequence')
    gulpif = require('gulp-if');

gulp.task('build', () => {
    runSequence('set-dev', 'css', 'set-prod', 'css');
});

gulp.task('set-dev', () => {
    vars.isProduction = false;
    vars.outputStyle = 'expanded';
});

gulp.task('set-prod', () => {
    vars.isProduction = true;
    vars.outputStyle = 'compressed';
});

gulp.task('css', function() {
    return gulp.src('scss/*.scss')
        .pipe(plumber()) // Deal with errors.
        .pipe(sourcemaps.init()) // Wrap tasks in a sourcemap.
        .pipe(sass({ // Compile Sass using LibSass.
            errLogToConsole: true,
            outputStyle: vars.outputStyle // Options: nested, expanded, compact, compressed
        }))
        .pipe(postcss([ // Parse with PostCSS plugins.
            autoprefixer(ap_options),
        ]))
        .pipe(gulpif(vars.isProduction(cssnano({ // Minify CSS
            safe: true // Use safe optimizations
        }))))
        .pipe(gulpif(vars.isProduction(rename({ suffix: '.min' })))) // Append our suffix to the name
        .pipe(sourcemaps.write('../maps')) // Create sourcemap.
        .pipe(gulp.dest('./css/')) // Create style.min.css.
        .pipe(gulpif(!vars.isProduction(livereload())));
});

EDIT

output the normal and compressed CSS from one task. You really just need two destinations

var gulp = require('gulp'),
    $ = require('gulp-load-plugins')();

gulp.task('css', function() {
    return gulp.src('scss/*.scss')
        .pipe(plumber()) // Deal with errors.
        .pipe($.sourcemaps.init()) // Wrap tasks in a sourcemap.
        .pipe($.sass({ // Compile Sass using LibSass.
            errLogToConsole: true,
            outputStyle: "expanded" // Options: nested, expanded, compact, compressed
        }))
        .pipe($.sourcemaps.write()) // Create sourcemap.
        .pipe(gulp.dest('./css/')) // Create style.min.css.
        //** MIN VERSION HERE
        .pipe($.sass({ // Compile Sass using LibSass.
            errLogToConsole: true,
            outputStyle: "compressed" // Options: nested, expanded, compact, compressed
        }))
        .pipe($.cleanCss({
            keepSpecialComments: '*',
            spaceAfterClosingBrace: true
        }))
        .pipe($.rename({ suffix: '.min' })) // Append our suffix to the name
        .pipe(gulp.dest('./css/'));
});
Duderino9000
  • 2,535
  • 4
  • 31
  • 37
  • Thanks for the ideas - thing is I still would like both files created if possible as the site uses the compressed one but I like generating the non-compressed one as well in-case I need to see how a certain block of css got generated. – Brett Sep 17 '16 at 15:48
  • If you run the `build` task it will create both files. The `set-*` tasks will just set the variables used in the `css` task. – Duderino9000 Sep 19 '16 at 16:44
  • How so? From what I can make out it will create _one_ file, that being the compressed version if it's production or an uncompressed version if it's NOT production. – Brett Sep 20 '16 at 17:07
  • Hmm, have you tried it? It should work because the `build` task calls the `css` task twice; once for the "expanded" css output file, and then again with the "compressed" CSS file. That `isProduction` flag will also toggle `gulp-rename` so the first time `css` is run you'll get `my-file.css` and the second time you'll get `my-file.min.css` – Duderino9000 Sep 20 '16 at 20:32
  • 1
    Oh ok........ I'm not very familiar with `runSequence` and didn't know the `css` task was being run twice. Bad thing though is this still has the overhead of having to process the scss files twice just like my initial version. – Brett Sep 21 '16 at 11:31
  • You are creating two different files though. The bright side is the JavaScript is DRY this way – Duderino9000 Sep 21 '16 at 17:01
  • True, but my main concern was avoiding running through the process twice and seeing if there was a way one could generate both files during the same task without executing the code twice. – Brett Sep 22 '16 at 13:19
  • I see now. I thought you meant efficiency like you're doubling up your code. See my edit, you really just need two destinations – Duderino9000 Sep 22 '16 at 18:14
  • Well I meant both, don't like doubling up on code either, but was mainly trying to avoid running the process more than I had to. :) – Brett Sep 22 '16 at 18:37
  • 1
    Ok just had a look at your edit........ but looks like you're still running the `sass` compilation twice? Is it not possible to run that once, save the results to the uncompressed version and then create the minified version? ...or will this not work out with creating the correct source maps? – Brett Sep 22 '16 at 18:46