Using GRUNT to automate development tasks: Part I

Here at Branded3, we’re always looking to improve our workflows and reduce the amount of overhead that certain tasks take.  With the rise of mobile responsive websites and Google’s increasing interest in quick-loading websites, we’re increasingly taking longer to ensure that CSS files are minified, JS is combined and minified, images are as compressed and clean as they can be etc.  We also use SASS and have been using SCOUT to live watch our files for some time.

The development team here uses a variety of tools, both online and offline to achieve what’s listed above. With this in mind, over the Christmas break I started looking for a set of tools that could combine this into a best practise for the team and to see if there was any “one” tool that would actually combine everything for us.

The open source team all use PHPStorm, so this is where I started my investigation.  PHPStorm has some great plugins – SASS, Minifying CSS or Combing and Minifying JS.

We’re all tech-savvy developers, but it quickly became apparent that combing all of these things meant that a lot could quickly go wrong working across different versions of operating systems and different versions of software. I also began to wonder about the .NET team, who use Visual Studio, and those occasions when we quickly edit files in programs like Sublime Text, or, for that matter any other editor.

At this point, I realised I should actually be looking for a tool that could sit outside of the development environment. I found a couple, but the one that really stood out was Grunt. Grunt is a Node.js task runner. It doesn’t “do” anything itself, other than run tasks you tell it to. It’s used by some big firms such as Twitter, jQuery, Adobe, WordPress and many others. You can do all sorts using GRUNT as a task master, and, it just so happens, you can do everything on my list. It’s worth pointing out, it also does a whole lot more. It can look a little cumbersome to begin with, however, once you’re set up, you can copy grunt config files into project folders and use the same one across them all if you so wish.

I’m going to take you through a quick setup guide for 64-bit Windows 7. I’m then going to configure a handful of useful tools for starters, and then let you take it from there.

Installing Node.js

Grunt uses Node.js as a platform – it uses its Package Manager, NPM.

To install Node.js, simply go to nodejs.org and hit install. It should detect which version is right for you and download it when you hit “install”, however, if it doesn’t, just go to their download page.

nodejs

I only ran into one issue whilst installing Node.js and that was that it didn’t add to my PATH variable. This meant that I couldn’t run NPM packages from any folder using the default command and I’d have to put in a full path. To avoid this, I added it to my PATH varibale myself. To do this, open Control Panel -> System -> Advanced System settings. Once here, click to the Advanced tab, and hit Environment Variables. You should notice “Path” in the top window. Click edit and add the path onto the end. I found it easier to copy and paste into notepad and then copy and paste back. So, I added C:\Users\Douglas.Radburn\AppData\Roaming\npm;C:\Program Files\nodejs

Installing & Configuring GRUNT

You install Grunt on a per-project basis.

You can either use Grunt on a new project, or integrate it into an existing project. Either way is simple!

Let’s start by going to your project’s folder. Here, you’ll need to create a file called package.json at the root level. You can just create one using your favourite editor and put it there. This file is used to configure Grunt – we’ll look at how this file changes as we progress adding modules.

For now, create the file with the following content (name can reflect your project):

Now, open up cmd and navigate to your project directory.

Type the following command:

npm install

After you’ve run this command, you’ll notice a new folder has been created – node_modules.

Next, you need to install the Grunt Command Line Interface (CLI). It’s best to do this globally, so that you only ever have to do this once.

npm install -g grunt-cli

Combining & Minifying CSS files

So, now we’ve got Grunt installed, let’s get it doing something.

We’re going to start by combining all our CSS, and then minifying it.

We want to do this for performance reasons – one request is obviously going to be quicker than multiple requests.

The first step is concatinating (combining) the files together.

Now, remember, Grunt is a Node.js task runner. It doesn’t do anything itself, it just runs tasks. Luckily, there are lots of contributed packages that Grunt can run in order to do all sorts. Concatinating is one of them, and the plugin is called grunt-contrib-concat

So, let’s get it installed. Go to your project diectory and type npm install grunt-contrib-concat --save-dev The NPM will automatically add reference to this package as a dependancy within your package.json file. This means when you come to use it on another machine, you can use npm install and it will download this package.

Now that this is installd, you need to tell Grunt what to do with it, and you tell Grunt what to do by using a configuration file – Gruntfile.js. So, lets set it up. You’ll need to create this file in the root of your project. For now, copy and paste the example below:

The example above is very simplistic. The configuration section loads the package.json file, and sets up the concat with specific settings. Below this, Grunt loads the correct packages and registers the tasks to run. In this example, we list two sources – a source folder, and a source file to combine, in to a destination file. Concatinating these files will be done in order. First the libs folder will be added, then the single file. Here, we use a build folder in order to distinguish the file within the source tree.

Now, you should be able to run Grunt.

Drop into a command prompt, change to your projct directory and type grunt. If all is right, you should find that lib/build/js/production.js has been generated. Don’t worry if the folder doesn’t exist, Grunt will create it.

Wow, it worked! So, what next? How about we minify the CSS?

We found that grunt-contrib-concat could concatinate files, and now we need to find a module that will minify. For this, we will use grunt-contrib-uglify. Install it in the same manner as grunt-contrib-concat by typing npm install grunt-contrib-uglify --save-dev in a command prompt in your prject directory.

Next, we need to modify your Gruntfile.js file. Open it in your favourite editor, and add grunt.loadNpmTasks('grunt-contrib-uglify'); beneath the grunt.loadNpmTasks('grunt-contrib-concat'); line we already have.

Additionally, we need add configuration settings:

And finally, we need to tell Grunt to run the configuration. We alter the grunt.registerTask('default', ['concat']); line to read:

grunt.registerTask('default', ['concat', 'uglify']);

Now if you run Grunt, you should find that lib/build/css/production.css and lib/build/css/production.min.css should be created.

Re-sampling Images

Services like Smush.it are great. We use them all the time. They losslessly compress your images by removing extra data (like meta). There are many services like it, and many plugins for popular platforms like WordPress – there is also a Python script that can be used to transverse folders.

One thing we found time and again was when templating a site, little bits change and with the best will in the world, by the end of a project, you probably end up with at least a couple of files you’ve missed or forgotten about along the way. Plugins are great for uploaded content, but they won’t touch template images.

So, can Grunt help? Of course it can!

The official image minification plug-in for Grunt is called grunt-contrib-imagemin.

You install it like previously:

npm install grunt-contrib-imagemin --save-dev

and load it in your gruntfile.js file like before:

grunt.loadNpmTasks('grunt-contrib-imagemin');

To configure image minification, we can specify any number of input directories, and then get it to pick certain filetypes and set up a destination folder for ouput. This could of course be the same folder if you’d like.

Make sure that you add the task to the registerTask function (grunt.registerTask('default', ['concat', 'uglify', 'imagemin']);

Note: With 64bit Windows, I had an issue during installation of the imagemin package that meant that JPG images couldn’t be minified. If you get the same issue, checkout this StackoverFlow article.

Round-up

To summarise, we should now have the ability to compress and minify CSS files (which could be easily ported to JS files too) and we can optimise our template images. We are however dependent on you running Grunt at regular intervals. In the next article I’ll be discussing how to get Grunt to “watch” for certain actions so that you can just leave it running in the background and it will automagically update and process. If you want to read ahead, check out grunt-contrib-watch.

By Douglas Radburn. at 11:12AM on Thursday, 16 Jan 2014

Doug is our Senior Open Source Web Developer since bringing his knowledge and skills to Branded3 in 2009. A founding developer of our Twitition and Competwition platforms, Doug has also been lead in our Open Source Projects on Magento ecommerce solutions and Wordpress CMS platforms. Follow Douglas Radburn on Twitter.

comments

Leave a Reply