cult3

Getting started with Grunt

Nov 11, 2013

Table of contents:

  1. What is Grunt?
  2. Why have I chosen Grunt over an Asset Pipeline?
  3. Installing Grunt
  4. The structure of a Grunt project
  5. Setting up a new Grunt project
  6. Creating the package.json file
  7. Creating the GruntFile.js file
  8. Conclusion

In last week’s article, I started using an Asset Pipeline to automatically compile my stylesheets from Sass into CSS and have it piped into my layout.

However, 7 days is a long time in the fickle world of Philip Brown, and so I’ve decided to replace the Asset Pipeline with Grunt instead.

In this article I will explain what Grunt is, why I have chosen to use Grunt instead of an Asset Pipeline and how to get started using Grunt in your projects too.

What is Grunt?

So before I get into explaining why I’m going to use Grunt, it’s pretty important that I explain what it is first, right?

Grunt is basically a system for automating repetitive jobs.

For example, every time you save your Sass or Javascript files, you will want certain actions to automatically run. For Sass files, you will want the Sass to compile down to CSS, and for Javascript files you will want them to be automatically checked and unit tested.

There are actually many ways to achieve this kind of automation, but the best thing about Grunt is the open and growing ecosystem of plugins that are available. This means you can have all of your automation in Grunt, rather than using many different tools.

Why have I chosen Grunt over an Asset Pipeline?

As I mentioned above, one of the best things about Grunt, in my opinion, is the open ecosystem of plugins. When I’m working on a project I like to cherry pick the best individual packages that are available to get the job done.

Using an open system like Grunt means I can very easily choose which bits of the stack I want to implement in any given project.

Secondly, I want to get Cribbb into a position where I can ship updates or install it locally or on a server with very little effort. Automation is the method for reducing human error, and so by getting Grunt to handle a lot of this repetitive work, I can concentrate on shipping high quality software.

Installing Grunt

As with all of my tutorials, I’m currently working on OS X. I won’t cover how to install Grunt on every operating system or version as it is beyond the scope of this article and I’m sure there are much better tutorials out there.

Grunt is actually a Node.js package so we can use NPM to install it. NPM is the Node.js equivalent of PHP Composer. If you don’t already have Node.js installed on your system, go do that first.

Next run the following command in Terminal:

npm install -g grunt-cli

The structure of a Grunt project

A Grunt project basically consists of two main files. Firstly there is package.json and secondly there is GruntFile.js.

The package.json is essentially the same as your composer.json file in that it lists meta data about your project and what dependancies are required.

The GruntFile.js is used to configure, and define the tasks that you want to be run on your project. The GruntFile is basically just a valid Javascript file that has a set of configurations and tasks for building your project.

Setting up a new Grunt project

To set up a new Grunt project, we basically just need to create the package.json and GruntFile.js files.

Creating the package.json file

There are a couple of ways of creating a package.json file.

Firstly you could run npm init from Terminal. This will ask you a couple of questions about your project and then it will automatically create the package.json file for you.

Alternatively, you can use one of the Grunt init templates. grunt-init is a scaffolding tool for creating new projects from a set template.

To install grunt-init, simply run npm install -g grunt-init from Terminal.

Next you can create a new project from an existing template. See the Grunt documentation for full details of these templates.

In my case, I’m simply going to run npm init. Some of the questions weren’t really relevant so I just deleted some of the sections once the init process had finished. You can always go back and add extra data to your package.json file at any point just by modifying the file. My file ended up looking like this:

{
    "name": "Cribbb",
    "version": "0.0.1"
}

Whenever you want to install Grunt plugins you can do so through Terminal. For example, to actually install Grunt into the project, we need to run:

npm install grunt -save-dev

This will create the node_modules folder and it will add the following lines to your package.json file.

{
    "devDependencies": {
        "grunt": "~0.4.1"
    }
}

We use the --save-dev flag to ensure that this plugin gets added to the package.json file. This means we can commit this file to version control so whenever someone wants to work on the project, they only have to run npm install to get going.

Finally, we’ll install the first Grunt Plugin Uglify:

npm install grunt-contrib-uglify -save-dev

Uglify is basically a compressor for Javascript. It will take big Javascript files and make them really small.

Creating the GruntFile.js file

Next we need to create the GruntFile.js file. This is where all the real heavy lifting occurs when using Grunt, so you will want to get accustomed to it so you can tweak your project to run exactly how you want it to.

As I mentioned above, the GruntFile.js is a valid Javascript file, so if you are familiar with Javascript, this shouldn’t be too difficult to pick up.

However, if you are not familiar with Javascript, the GruntFile.js is basically comprised of the following sections.

Wrapper

module.exports = function (grunt) {
  // Grunt goodness goes here
};

All of your Grunt code should sit within this wrapper function. This is a common structure in Javascript.

Project and Task configuration

// Project configuration.
grunt.initConfig({
  // Package
  pkg: grunt.file.readJSON("package.json"),

  // Uglify
  uglify: {
    options: {
      banner:
        '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n',
    },
    build: {
      src: "src/<%= pkg.name %>.js",
      dest: "build/<%= pkg.name %>.min.js",
    },
  },
});

Next we have the Project and Task configuration section. This is basically where you set the configuration of the project.

Firstly we grab a copy of the package.json. This allows us to import the meta data about the project into the GruntFile to use within template tags. For example, would use the project’s name.

Next we can set the configuration for each of the tasks that we want to run. In this case I’ve set the configuration for the Uglify plugin.

In this example, I’m setting a banner:

options: {
  banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n';
}

And a simple build option that will get a single file from the source and output a single uglified file:

{
    build: {
        src: 'src/<%= pkg.name %>.js',
        dest: 'build/<%= pkg.name %>.min.js'
    }
}

For a full list of the Uglify options, take a look at the GitHub page.

Load plugins

grunt.loadNpmTasks("grunt-contrib-uglify");

Next we load our required plugins. It’s important to note that this will not automatically install the plugin in to the project. You are still required to run the install command from earlier.

Set tasks

grunt.registerTask("default", ["uglify"]);

And finally we can set up tasks that should be run on certain commands. In this very simple example above, Uglify will be run whenever the grunt command is run from Terminal.

This allows you to set up different task lists. For example, you might want a build task list that would run a different set of tasks than what you want to run for your development environment.

You could then run the following command whenever you wanted to ship new code to production:

grunt build

So once you have saved your GruntFile.js, set up a Javascript file at the path that you defined in the Uglify configuration, run grunt in Terminal and you should find the uglified file under you destination folder.

Conclusion

So hopefully you are starting to see the huge benefits of using a task runner like Grunt. Grunt makes automating all of these types of jobs much easier and helps you along the path to shipping really high quality code.

We have barely even scratched the surface with Grunt as there is so much you can do with it. In next week’s tutorial we’ll be taking a much deeper dive into setting up a lot of automated tasks and a much more comprehensive GruntFile.js to do some really cool things with Grunt.

This is a series of posts on building an entire Open Source application called Cribbb. All of the tutorials will be free to web, and all of the code is available on GitHub.

Philip Brown

@philipbrown

© Yellow Flag Ltd 2024.