Jntz
11/4/2015 - 10:28 AM

Live-reload and fast CSS compilation for a SilverStripe website using gulp.js

Live-reload and fast CSS compilation for a SilverStripe website using gulp.js

Live-reload and fast CSS compilation for a SilverStripe website using gulp.js

Steps to success:

  1. Install gulp globally (do this only once): npm install -g gulp
  2. In your project folder, add gulp: npm install --save-dev gulp
  3. Install browser-sync to enable auto-updated and synchronised websites across all your browsers: npm install -g browser-sync
  4. Install libsass for super fast SCSS compilation: npm install --save-dev gulp-sass
  5. Install sourcemaps-plugin if you want them: npm install --save-dev gulp-sourcemaps
  6. Of course you can also add gulp plugins to concatenate and minify your JavaScript and CSS.

gulpfile.js

A basic gulp-file could look like this:

'use strict';

// require gulp itself
var gulp = require('gulp');

// require the sass and sourcemaps plugins
var sass = require('gulp-sass');
var sourcemaps = require('gulp-sourcemaps');

// create a browser-sync instane
var browserSync = require('browser-sync').create();

// Paths to your sass and css directories
var SASS_SRC = './themes/mytheme/sass';
var CSS_DIR = './themes/mytheme/css';

// url where browser-sync should serve files from 
// (eg. your local silverstripe installation url)
var PROXY_URL = 'localhost/silverstripe-site';

// Build CSS files from sass and create sourcemaps
gulp.task('sass', function (cb) {
    gulp.src(SASS_SRC + '/*.scss')
        .pipe(sourcemaps.init())
        .pipe(sass().on('error', sass.logError))
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest(CSS_DIR))
        .pipe(browserSync.stream());
    // call the callback to signal that task is finished
    // useful for task sequencing, such as compile css and minify
    cb();
});

// If you only want to watch changes to scss files and don't want to
// use browser-sync, you can use this task by invoking `gulp sass:watch`
gulp.task('sass:watch', function () {
    gulp.watch(SASS_SRC +'/*.scss', ['sass']);
});

// This is the task that initializes browser-sync
gulp.task('serve', function () {

    // Serve files from the root of this project
    browserSync.init({
        proxy: PROXY_URL,
        files: [
            // Patterns for static files to watch. 
            // We're watching js and php files within mysite
            // and SilverStripe template files within themes
            "mysite/**/*.js",
            "mysite/**/*.php",
            "themes/**/*.ss"
        ],
        notify: false
    });
    
    // watch changes to sass (these will also be piped to browser-sync)
    gulp.watch(SASS_SRC +'/*.scss', ['sass']);
});

// the gulp default task just invokes sass compilation
gulp.task('default', ['sass']);

Now you're ready to start developing using browser-sync and libsass. Just run gulp serve.

Some more useful tasks (can be added to the gulp-file above)

Concatenate and minify CSS

// required plugins
// install with: npm install --save-dev gulp-concat-css gulp-uglifycss
var concatCss = require('gulp-concat-css');
var uglifyCss = require('gulp-uglifycss');

// Merge layout and typography into one file and minify it
// Run the sass task first.
gulp.task('minify-css', ['sass'], function(){
    gulp.src([
        CSS_DIR + '/layout.css',
        CSS_DIR + '/typography.css'
    ], {base: CSS_DIR})
        .pipe(concatCss('styles.css'))
        .pipe(uglifyCss())
        .pipe(gulp.dest(CSS_DIR));
});

Concatenate and minify JavaScript

// required plugins
// install with: npm install --save-dev gulp-concat gulp-uglify
var uglify = require('gulp-uglify');
var concat = require('gulp-concat');

// define the JavaScript destination folder
var JS_DST = './themes/mytheme/javascript';

// define the files you want to merge
var JS_FILES = [
    'bower_components/jquery/dist/jquery.js',
    'bower_components/picturefill/dist/picturefill.js',
    'bower_components/jquery-cycle2/build/jquery.cycle2.js',
    'bower_components/jquery-cycle2/src/jquery.cycle2.swipe.js',
    'mysite/javascript-dev/init.js'
];

// merge and minify all the JS files into script.min.js
gulp.task('minify-js', function(){
    return gulp.src(JS_FILES)
        .pipe(concat('script.min.js'))
        .pipe(uglify())
        .pipe(gulp.dest(JS_DST));
});

Updating the default task

When you add new tasks, you might want to check/update your default task. So instead of having:

gulp.task('default', ['sass']);

You might now prefer:

// minify-css invokes sass for you, so no need to add that here again
gulp.task('default', ['minify-js', 'minify-css]);

Running gulp will now minify your CSS and JS.