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.