9 févr. 2014

A gulp of coffee: your gulpfile in coffeescript

Pros and cons

Gulp is  a new buildsystem for the web. It contrasts with Grunt by leveraging NodeJS's streams. Therefore, it writes no temporary file on your drive when you're performing multiple operations on your assets. Of course, it speeds up the build process, but it is not the only advantage. Thanks to the streams, when you write your tasks, it feels more like you are describing the required workflow. For me, it is much more natural.

The main drawback that I've found is its inability to directly use CoffeeScript as its main file. Streams and their piping abilities produce a ton of parenthesis obfuscating the semantic of your development with unnecessary grammar and syntax requirements.

Regaining access to CoffeeScript

Like GruntGulp expect a main file named Gulpfile.js. We will use this file to bootstrap CoffeeScript and, thus, regain access to a more friendly language. Of course, the same trick could be applied to other languages such as Dart or TypeScript.

// Note the new way of requesting CoffeeScript since 1.7.x
// This bootstraps your Gulp's main file

That's it.

Now, just an example that demonstrates the achieved advantage, and also, the new parenthesis free chaining of CoffeeScript 1.7. The following script transpiles Jade, minifies it, compresses your SVG, transpiles your Sass, autoprefix it and minifies it, copies the fonts used in your Sass files.

# Load all required libraries.
gulp       = require 'gulp'
sass       = require 'gulp-ruby-sass'
prefix     = require 'gulp-autoprefixer'
cssmin     = require 'gulp-cssmin'
jade       = require 'gulp-jade'
minifyHTML = require 'gulp-minify-html'
svgmin     = require 'gulp-svgmin'

# Create your CSS from Sass, Autoprexif it to target 99%
#  of web browsers, minifies it.
gulp.task 'css', ->
  gulp.src 'app/css/index.sass'
    .pipe sass()
    .pipe prefix "> 1%"
    .pipe cssmin keepSpecialComments: 0
    .pipe gulp.dest 'www/css'

# Create you HTML from Jade, Adds an additional step of
#  minification for filters (like markdown) that are not
#  minified by Jade.
gulp.task 'html', ->
  gulp.src 'app/index.jade'
    .pipe jade()
    .pipe minifyHTML()
    .pipe gulp.dest 'www'

# Minify your SVG.
gulp.task 'svg', ->
  gulp.src 'app/img/*.svg'
    .pipe svgmin()
    .pipe gulp.dest 'www/img'

# Copy the fonts using streams.
gulp.task 'copy', ->
  gulp.src 'app/fonts/*'
    .pipe gulp.dest 'www/fonts'

# Default task call every tasks created so far.
gulp.task 'default', ['css', 'html', 'svg', 'copy']