Your browser doesn’t support some of the latest CSS features used to build this site.

Read more about my usage of new CSS features.

Further lessons in overcoming the learning curve on new front end technologies, this post focuses on Grunt - the JavaScript task runner.

BG: Before Grunt

Before I started using Grunt for personal projects my only real experience of a build process was using NAnt on a build server to concatenate and minify files for production deploys - using all unminified seperate CSS and JavaScript files locally with no real front end build.

Retrospectively this was a little messy and didn’t allow us too much control over what our build process was doing.

Enter the Grunt…

Grunt JS Logo
Grunt does look a bit scary to be fair…

Grunt is…

A task runner, helping you automate the repetitive tasks in a front end build process - which in my opinion leads to vastly reduced human error and greatly speeds up workflow.

It can be used for a myriad of tasks, with over 3,638* plugins currently written for it.

*correct at the time of writing.

Prerequisites

  1. NodeJS. That is all.

Let’s get set up

First, install Grunt and the Grunt command line tools globally.

npm i grunt grunt-cli -g

Next create a directory for your project and enter it.

mkdir test && cd test

Next enter npm init if your project doesn’t already have a package.json file and follow the instructions to set it all up.

Installing Grunt plugins

To install your first plugin (let’s choose cssmin), enter the following command:

npm install grunt-contrib-cssmin -D

Setting up the task

You’ll need a Gruntfile.js in which you should have as a minimum:

module.exports = function(grunt) {
  grunt.initConfig({
    // Task configuration goes here
  });

  grunt.registerTask('default', [
    // Tasks registered here
  ]);
};

In the grunt.initConfig({ }); goes your task configuration objects. An example for the task we installed earlier grunt-contrib-cssmin is as follows:

cssmin: {
  options: {
    banner: 'Latest build: <%= grunt.template.today(\'dd/mm/yyyy') %>'
  },
  main: {
    src: 'src/assets/styles/main.css',
    dest: 'dist/assets/styles/main.min.css'
  }
}

This task for example takes in a banner as an option to add to the top of your minified CSS file, takes main.css as input and outputs the minified file to your /dist folder.

Further plugins

The README documents in the majority of Grunt plugins give straightforward examples of the config object required per task, so I’ll leave you to your own devices to scour the plethora of Grunt plugins available and add some to your Gruntfile.js.

Here’s a few of my favourite, essential Grunt plugins:

Be sure to come back for some advanced tips!

Expert mode!

1. Reusable configuration objects

And now for some more advanced tips to optimise and tidy up your Gruntfile.

To enable reuse of file locations, keeping them consistent throughout your Gruntfile and avoiding redundant repetition, add a config object as follows:

config: {
  // Src settings
  src: 'src',
  srcAssets: 'assets',
  // Dist settings
  dist: 'dist',
  distAssets: '_assets',
}

And you can then refer to this in your tasks by using Lo-Dash style delimeters like this:

src: '<%= config.src %>',
  dest '<%= config.dist %>'

So if you ever need to change the location it now only needs to be updated in one place!

2. Reading in external files

You can also read external files such as your .bowerrc, bower.json or package.json to use information about your project in your tasks.

pkg: grunt.file.readJSON('package.json'),
    bowerrc: grunt.file.readJSON('.bowerrc'),

    // And use as follows:
    config: {
    bowerDirectory: '<%= bowerrc.directory %>',
    packageJson: '<%= pkg %>'
  },

3. Banners

A great way to add dynamically generated content to your distribution files is by the use of a banner. Many plugins such as the aforementioned CSSMin allow banners to be added to the top of produced files.

An example of this could be to prepend the build time to your minified CSS file:

// In the config
    meta: {
    banner: '/* <%= pkg.name %> :: Latest build: <%= grunt.template.today(\'dd/mm/yyyy, h:MM:ss TT\') %> */\n'
  },

  // In the task
  cssmin: {
  options: {
  banner: '<%= meta.banner %>'
},
}

TL;DR

This post served as a short but sweet introduction to Grunt, the JavaScript task runner.

Grunt is a powerful tool that I’ve only briefly touched on in this blog, but I’ll be adding more advanced tips in a future post.

Bonus: Here’s a link to my Gruntfile for reference - its pretty beasty, so take a long look!