Mícéal Gallagher in Grunt 3 minutes

Atomatically minimizing CSS and JS with Grunt

When depolying to the web it’s a good idea to minify your text based assets.

What do we mean when we say minify? The objective of minification is to reduce the content of the files while preserving their functionality, this is done by doing the following:

  • shorten variable names
  • remove whitespace
  • remove comments

So the following javascript…

var firstName = $("#firstname").text();
if (firstName.length > 0) {
    console.log("Value:" + firstName);
} else {
    alert("Please provide a valid first name");
}

…to the following…

var a=$("#firstname").text();a.length>0?console.log("Value:"+a):alert("Please provide a valid first name");

It doesn’t look like much but in this example we have reduce this JS snippet from 165 to 108 characters. This is a 35% reduction in content that needs to be transferred.

To take the minification process one step further we could combine all the JS and CS into one file each; resulting in fewer web requests to render the page.

Now we’ll use grunt to minify some resources. I’m going to assume you’ve got the grunt-cli installed for your project.

Lets install a few plugins. We are going to use uglify, cssmin and watch install these via NPM. Be sure to use the --save-dev switch to automatically add them to the Gruntfile.

npm install grunt-contrib-uglify --save-dev
npm install grunt-contrib-cssmin --save-dev
npm install grunt-contrib-watch --save-dev

Now we will create our uglify and cssmin tasks in the Grunt wrapper function.

First uglify:

...
uglify: {
  build: {
    src: 'assets/js/main.js',
    dest: 'assets/js/main.min.js'
  }
},
...

Now, cssmin:

...
cssmin: {
  target: {
    files: {
      'assets/css/style.min.css': ['assets/css/style.css']
    }
  }
}
...

The uglify and cssmin tasks will be executed each time we execute grunt within our project directory. What would be ideal is if these tasks were executed each time main.js and style.css files are modified. This can be accomplished with grunt-contrib-watch.

Let’s add the watch task to the Gruntfile. Notice that we are asking watch to monitor the main.js and style.css files for changes. When modifications are detected run the uglify and cssmin tasks respectively.

...
watch: {
  scripts: {
    files: ['assets/js/main.js'],
    tasks: ['uglify']
  },
  css: {
    files: 'assets/css/style.css',
    tasks: ['cssmin'],
  },
},
...

I find this technique useful on a daily basis. To take things a step further, I’d recommend looking into the livereload option for grunt-contrib-watch which automatically reloads a browser tab when tasks have completed.