Brett
Brett

Reputation: 20049

Creating standard and compressed css files when using Gulp efficiently

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?

Upvotes: 4

Views: 3884

Answers (1)

Duderino9000
Duderino9000

Reputation: 2597

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/'));
});

Upvotes: 2

Related Questions