JavaScript/AngularJS adventures of a Java guy Part 3 – Grunt

grunt

In Part 2, I talked about managing dependencies with Bower. The next step is to see how to execute build tasks.

For example, when you build with Maven, one of the default behaviors is to copy the contents of src/resources to your build directory (target). We can do things like that with a tool named Grunt.

Grunt

There are currently two task tools for JavaScript. (I haven’t looked in the past 2 minutes, but there may be more now.) Grunt is the one that is most in use right now. Grunt uses JSON to configure the tasks. Gulp is a newer tool that uses JavaScript for configuration. Gulp benefits from hindsight and tries to avoid some of Grunt’s inconveniences. Personally, I don’t think you can go wrong using either tool.

Installation

If you’ve followed along with the previous blog posts, you already have npm installed. Grunt is installed globally (not per project) via npm with this incantation:

This “command line interface (cli)” puts the command “grunt” on your path, so you do not have to type “npm grunt” or even worse “./node_modules/.bin/grunt”.

The minimal project

You need two files in your project: Grunt’s Gruntfile.js which describes the tasks you wish to execute, and npm’s package.json, which specifies general project information along with dependencies.

You can create a package.json file by hand, or by invoking npm init and answering the prompts.
Here is a simple “by hand” package.json:

To use Grunt, you will need to add it to package.json as a development dependency, and then install it. This can be accomplished with the following command.

List the directory node_modules, and you’ll see grunt there. (You may be a later version, of course).

Now take a look at package.json to see the added dependency.

The gruntfile can be written in JavaScript or CoffeeScript. I’ll just use JavaScript here.

Here is a simple Gruntfile.js – that does nothing! (Actually, it registers a default task that does nothing).

Each Gruntfile.js will have this format. You can run this by typing:

Adding Grunt Tasks

Grunt tasks are defined by plugins. There is a registry of Grunt plugins.

Let’s start with the concat task.
Install the task.

This updates node_modules (go ahead and list it), and modifies package.json:

This is what you will do with each Grunt plugin: npm install pluginname –save-dev

Now in Gruntfile.js, you will have to add this task.
grunt.loadNpmTasks(‘grunt-contrib-concat’);
That is not enough. We need to tell the task what files it should concatenate, and where it should put the output. You configure all tasks in grunt by invoking grunt.initConfig(configObject); The configObject contains the configuration for each task you’re going to use. Here is an example for concat.

In grunt.initConfig, I’m defining a target named dist in the concat task. You can specify multiple targets. At a minimum you need to specify the source files and the destination as shown. These file can be – and probably are – in subdirectories such as src/a.js and distribution/built.js. You can also specify file globbing of course.

Because I defined the “default” task as containing ‘concat’, you can run this by simply typing grunt. You will have multiple tasks in a real build, so to execute a specific task you can type the name: grunt concat.

Here is the concat task with two targets: dist and bar. Note that they write to the same destination file. When you run grunt concat, all the targets are executed. That means in this case that the output of dist will be overwritten by the output of bar. So, be careful here; I wouldn’t write targets like this in a real project. If you want to run just one target, type grunt concat:dist or grunt concat:bar.

Copy task

To copy files, install the copy task, then load it into your gruntfile as you did with the concat task using loadNpmTasks.

And the Gruntfile with the two tasks loaded and configured.

Live reloading

You know how you change your html, css, or js files in your editor, then switch to your browser and hit reload to see the new wonders you have just wrought?
Wouldn’t it be nice to have your browser reload automatically? That’s what the watch task is for.
(The livereload task has been deprecated in favor of the watch task).

Do the usual installation chacha:

Then load it into your gruntfile:

grunt.loadNpmTasks(‘grunt-contrib-watch’);

Install the LiveReload Chrome Extension. Configure the extension to “Allow access to file URLs”.

Scaffolding

You can get a bit of help from
grunt-init
which reads “templates” that you install into ~/.grunt-init. They are sort of like Maven archetypes.
First install grunt-init

Now install a template. Here is one that just sets up the gruntfile.

then use it

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.