Home / Blog / Grunt tips
Blog

Grunt tips

Grunt tips

Grunt tips

I've heard plenty of developers talk about how being "lazy" has pushed them into using build scripts, but that's not being fair to the value that can be achieved from a good build script. It's not about being lazy, it's about being smart. The whole point of automation is to let computers do what they do best, and that is to follow instructions.

Build scripts are anything but new, but the environment has changed, so naturally the tools do as well. You may (or may not) be familiar with make, ant, Rake or another build tool, the principles are the same but the implementation is different.

Grunt and it's tasks are developed in JavaScript and as such, they require nodejs and npm to e installed on your system. If that's already done, you can go ahead and install Grunt globally so that we can use it in any of our projects.

npm install -g grunt-cli

Let's use a static website as an example project. Given that it's static you might not think it requires much automation but there are a few things that would be very useful. Consider that as our website grows, we have a dozen or more individual JavaScript files, each one being requested individually - and making our users wait for them all to load before doing anything useful. The same goes for CSS files, or possibly even optimizing your website's images. I could come up with a few more, but you're already here so you must have your own ideas of what a build too can do for your project.

If you don't already have a package.json in the root folder of your project, you can type

npm init

That will walk you through creating one. It's the package.json that records which npm modules (and Grunt tasks) need to be installed for various elements of the project to work. A package.json file has two sections of interest here. One is "dependencies" and the other is "devDependencies". The Grunt tasks we'll be using won't be used when the project is deployed, so we'll add them to our "devDependencies" by installing them with "--save-dev". Starting with a simple example, lets install "grunt-contrib-concat" that lets us put all our JavaScript into a single file. This will allow us to use a single HTML include and sidestep the network latency required to fetch a dozen separate files on page load.

Install the grunt concatenation task with the following command:

npm install grunt-contrib-concat --save-dev

If you look at the package.json, you'll see that there are two new entries in devDependencies. One for Grunt itself, and one for the module we just installed. That means that the next developer working on your project can simply run "npm install" and get all the necessary modules.

In order to use Grunt, we need to create a gruntfile where all of our tasks will be defined. A gruntfile is simply a JavaScript file with the name "Gruntfile.js" that you keep in the root of your project and run by simply typing "grunt". A gruntfile for our project so far might look like this:


module.exports = function(grunt) {

  // Initialize grunt by loading the package.json and define our tasks.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    concat: {
      stuff: {
        src: [ 'src/foo.txt',
                'src/bar.txt',
                'src/baz.txt' ],
        dest: 'dist/foobarbaz.txt'
      }
    }
  });

  // Load any required modules previously installed via npm.
  grunt.loadNpmTasks('grunt-contrib-concat');

  // Define a default task.
  // Additional named tasks can be registered here as well.
  grunt.registerTask('default', ['concat']);

};

If you've been working with Nodejs at all you're already familiar with the "module.exports" used here. It exposes a function that takes a single parameter usually named 'grunt'. This parameter is then used within your function to load your package.json, define your tasks, load the grunt task plugins (or modules) and finally register them to be called or exposed to the grunt-cli.

Running "grunt" from the root of our project folder will execute the default task and the three files in our /src folder will get concatenated into a new file within the /dist folder in our project root. There are options for grunt-contrib-concat that tell the task what separator to use between files, banner and footer text to insert, and source map creating etc.

There are a many plugins available, you can find them at gruntjs.com/plugins. The "official" grunt plugins, maintained by the grunt.js project team, have names beginning with "grunt-contrib-" and third-party plugins are usually prefixed with "grunt-", but it's not a hard requirement. Look over the list to see what others are doing with grunt.js, and get some ideas for automating your own projects! If you don't find a task that does quite what you need, they're written in JavaScript so with a little work you could modify an existing task or start from scratch and roll your own.

Mark Voorberg

Co-Founder

Mark has been doing database design and building custom software for over twenty years. With a background in electronics, he quickly moved into software development and has been building database software solutions ever since, on many projects of all sizes.