Skip to content

Skeleton Sass with Modern Workflows

Dennis Thompson edited this page Jul 17, 2017 · 1 revision

Modern Workflows

We'll outline and explore modern workflows using Skeleton Sass.

Technologies dicussed below are:

  • Gulp
  • Rollup
  • Webpack 2+
  • Yarn

gulp is a workflow manager which runs tasks as part of your apps build lifecycle. Workflows like this when building modern web apps have replaced archaic methods of transpiling Skeleton Sass with the official sass gem in favor of building with libsass, generating sourcemaps, and allowing gulp to deposit our shiny new boilerplate in the directory of our choosing.

Let's setup a sample app:

  1. Open your terminal and setup a new NPM project

    yarn init -y
    touch gulpfile.js
  2. Now we need to install dependencies:

    yarn add skeleton-sass-official gulp-sourcemaps del cssnano gulp-sass gulp-postcss autoprefixer doiuse gulp-sass-lint --dev
  3. Once all our dependencies are installed, we need to write our gulpfile

    touch gulpfile.js

    Open the file in your favorite text editor:

    const gulp = require('gulp'); // node 4.x+ only, use var if using a version less than 4.x
    const sass = require('gulp-sass');
    const del = require('del');
    const sourcemaps = require('gulp-sourcemaps');
    const sassLint = require('gulp-sass-lint');
    
    // PostCSS
    const autoprefixer = require('autoprefixer')
    const cssnano = require('cssnano');
    const postcss = require('gulp-postcss');
    const doiuse = require('doiuse');
    
    gulp.task('clean', function () {
        return del('target'); // change to your build directory
    });
    
    gulp.task('sass', ['clean'], function () { // run clean before sass
        return gulp.src('main.scss')
            .pipe(sourcemaps.init())
            .pipe(sass().on('error', sass.logError))
            .pipe(postcss([
                autoprefixer({ browsers: ['last 1 version', ' >= 1%'] }),
                cssnano(),
                doiuse({ browsers: ['last 1 version', ' >= 1%'] })
            ]))
            .pipe(sourcemaps.write()) // inline sourcemaps
            .pipe(gulp.dest('target/css/'));
    });
    
    gulp.task('default', ['sass']); // default gulp task

    Let's examine our setup:

    1. We ask node to load gulp which exposes a "class" that contains a task method. This allows us to write our task in the format of:

      gulp.task('NAME', callback)

      Where callback is a function.

    2. In our calback, we return gulp.src() which gives us back a stream of files

    3. We call .pipe on our stream which either manipulates our data or inspects it for errors/gotchas

    4. At the end, we call .pipe one last time with gulp.dest() which tells gulp to write the contents of the stream to a file on our local disk.

    For more info on the inner-workings on gulp see their API docs.

PostCSS Ecosystem

The inquisitive reader may be asking themselves, "why do I need so many plugins to get this to work?"

Good question. The above example utilizies the following PostCSS:

  1. Autoprefixer
    • A handy plugin that automatically adds vendor prefixes for you
  2. CSS Nano
    • A CSS minifier
  3. Do I Use?
    • Queries caniuse.com/ databases to help avoid pitfalls and cross-browser gotchas

Is there a simplier way without all these dependencies? Yes. Modify your gulpfile.js as follows:

gulp.task('sass', ['clean'], function () { // run clean before sass
    return gulp.src('main.scss')
        .pipe(sourcemaps.init())
        .pipe(sass({ outputStyle: 'compressed' }).on('error', sass.logError)) // minify outout using libsass
        .pipe(sourcemaps.write()) // inline sourcemaps
        .pipe(gulp.dest('target/css/'));
});