Right so I’ve made the leap.
After quite a ride, and some cool adventures with Codekit, I’ve decided to switch to Grunt. I had made the plan way before it became the hot topic of the month, before being relegated to second best to Gulp… lol, you’ve got to love this ever-changing technology and probably laugh at it sometimes too.
Anyway, don’t even start with Gulp, I’ve just made it to the grunt deck for less that a month or so and since I’m still taking baby grunting steps, I thought I’d share the reason of my decision and maybe my minimalistic grunt boilerplate in case you’d be interested.
Valid reasons
Codekit has been a good companion all this time and will remain one for smaller projects (Mixture is also a cool one too when it comes down to prototyping), … but those tools have been magic as long as it was me, myself and I working on a project.
The thing is… it’s getting more complicated now. I’ve started working with other people, we do some responsive web design (just html/css/js) that we later move and adapt to the salesforce.com platform. We use some new tools, we’re working remotely and not everybody is using Macs.
I know Prepros is a good option for windows users, I wrote about it at the time it went out. And I know you can export your Codekit settings and share them among mac users and all. But with version control driving the lot, it has become clear we needed a common ground as far as all this preprocessing-minification-optimisation business is concerned.
Cut a long story short: Gruntjs is next logical step.
I’ve been playing with grunt for a wee while – I was saying- and since a boilerplate was on the cards all this time, let’s take a look at the one I’ve made… for myself first and obviously for the small team I’m working with.
My grunt wish list
- javascript error detecting tool.
- javascript minification
- some preprocessing with sass
- auto-prefixing
- image optimisation
- automatic browser refreshing when html/css/js changes occur
- work in html only (fed up php)
- yet a templating system
- and an automatic building process of the (optimised) lot
I’m restricting this list to something small to start off. Obviously more shall come, Autoprefixer (UPDATE January 27th 2014: now added), deployement to only name a couple.
Set up
You need node and npm and you need to read this getting started guide.
Install grunt with:
npm install -g grunt-cli
Create a package.json file at the root of your project like this one:
{
"name": "my-project-name",
"version": "0.1.0",
"devDependencies": {
"grunt": "~0.4.2"
}
}
Modules install
Install stuff by using:
npm install--save-dev
Create a Gruntfile.js at the root of your folder too, and update it as many times as you add modules like so:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
task1: {
options: {
}
},
task2: {
}
});
// Load the plugin that provides the tasks.
grunt.loadNpmTasks('grunt-task1');
grunt.loadNpmTasks('grunt-task2');
// Default task(s).
grunt.registerTask('default', ['task1','task2']);
};
This is how I do it. Some people prefer using load-grunt-tasks and only include require(‘load-grunt-tasks’)(grunt); at the top of their Gruntfile.js (check the documentation).
I personally don’t as I always leave rubbish in my node modules folder and I’d rather write and control what I use instead of taking the lot for granted.
My current folder and files setup is as follows (make it your own obviously):
Picking Modules
Javascript error detecting tool : grunt-contrib-jshint
jshint: {
all: 'js/*.js'
}
Explanation: Let’s check out all javascript files in the js folder (all but libraries really, as in the ones you’re likely to fuck up by hand).
Javascript minification: grunt-contrib-uglify
uglify: {
options: {
mangle: false
},
dist: {
files: {
'build/js/myscript.js': ['js/libs/jquery.js','js/libs/*.js','js/*.js']
}
}
}
Explanation: You need mangle:false in there for some reason I don’t know (lol), and for the rest, let’s get (in that sequence order) jquery, the rest of the library .js files, then your own custom js files minified into build/js/myscript.js.
Sass pre-processing: grunt-contrib-sass
sass: {
dist: {
options: {
style: 'compressed'
},
files: {
'build/css/global.min.css': 'scss/global.scss'
}
}
}
Explanation: Easy peasy with Sass. Note that I import all my _.scss files in a global.scss and have only this one compressed into build/css/global.min.css
Autoprefixing: grunt-autoprefixer
autoprefixer: {
dist: {
files: {
'build/css/global.min.auto.css': 'build/css/global.min.css'
}
}
},
Explanation: Here, I’m asking autoprefixer to check my css and add the relevant browser prefixes. global.min.css is changed to global.min.auto.css.
Image optimisation: grunt-contrib-imagemin
imagemin: {
dist: {
options: {
cache: false
},
files: [{
expand: true,
cwd: 'images',
src: ['*.{png,jpg,gif}'],
dest: 'build/images/'
}]
}
}
Explanation: Working on raw image samples (from the images folder) and outputting the optimised versions of png/jpg/gif files in build/images
Note: I have added the cache:false options to the module after noticing I was often getting empty files during optimisation.
HTML includes: grunt-includes
includes: {
files: {
src: ['pages/*.html'],
dest: 'build',
flatten: true,
cwd: '.',
options: {
silent: true,
}
}
}
Explanation: Just follow the spec to be able to add include your includes/file.html in any of your pages. And send it all to the build folder.
Note: simply add the below line within your page when adding a component (or include):
include "../include/footer.html"
Watch (and Livereload): grunt-contrib-watch
watch: {
js: {
files: 'js/*.js',
tasks: ['jshint','uglify'],
options: {
spawn: false,
livereload: true
}
},
css: {
files: '**/*.scss',
tasks: ['sass','autoprefixer'],
options: {
spawn: false,
livereload: true
}
},
files: '**/*.html',
tasks: ['includes'],
options: {
spawn: false,
livereload: true
}
}
Explanation: Here in the settings, I’m separating the various tasks so the watch task doesn’t do the full reprocessing every time something is changed. I’m running jshint and uglify for javascript files, sass for scss changes, and includes for html changes.
Note: You’ll need the Livereload chrome extension installed in your favourite browser for this one.
Build: all the above + grunt-contrib-copy
Explanation: Most of the things i’m running above builds up my final folder, but I wanted to be able to put that entire folder in the trash whenever I wanted to start the building process from scratch. So I simply ran an additional task in order to duplicate my fonts folder into build/fonts.
Wrapping up
This is it.
Running grunt in the terminal (our default task) would build the lot from scratch and we would get an optimised and working build directory.
Meanwhile, grunt watch (and the livereload extension turned on) will pick on any changes made to any of the html/css/js. Simply browse to your build folder while working on your project.
You will notice that No MAMP nor php includes are needed here while we have a full and customisable website templating system.
This may not be the way you work. After all, I’m far from a conventional developer (never really learned the stuff as I’m very much autodidact), but this process and folder structure suits me. It’s simple enough and since I won’t be industrializing it, it does exactly what I need it to do.
So long.
Note: Github repo now available.

My name is Flo Preynat and I am the freelance webdesigner and developer behind shoogle designs. I live in France and specialize in responsive web design. Give me a shoogle or get in touch with me on twitter.
Follow @shoogledesigns







Nice post. Will have to look into the plugins.
Autoprefixer on paper seems really good, I will have to test it and let you know.
Just added autoprefixer to the boilerplate for your info.
it’s setup as an additional watch command.
it takes the global.min.css to a new global.min.auto.css state.
If you have used the first version of this boilerplate, note that I have since added the cache:false options to the imagemin module to solve the empty file issue I was having while running the grunt task.
Hi Flo,
Nice read. I’m a huge fan of Grunt (I’ve built my whole boilerplate with it). It’s quite amazing to setup your workflow exactly like you want to instead of relying on tools which may not offer all the options one is looking for.
That being said, I have to admit that Gulp is quite amazing too. I suggest you take a look at it as a next logical step
Thanks mate. I will probably take a look sooner than I think as I’m hearing good reviews of it.