Configuring the package.json and Gruntfile.js files

This post is part 2 of 2 in the series Goin Hog Wild with Grunt

  1. Introducing and Installing Grunt Task Runner
  2. Configuring the package.json and Gruntfile.js files

Video Transcript

Hi, my name is Mike McLin and in this video I am going to talk about the 2 files that are required for Grunt Task Runner to function. The first is the package.json file which we’ll use to describe metadata about our project, like the name, version number, etc. We will also use this file to load the necessary plugins required by Grunt. From there I’ll discuss the second file required for Grunt to function, which is the Gruntfile.js. This is your main configuration file, and where we’ll spend most of the time in this video. The Gruntfile.js is where everything really happens. So, let’s get started by creating our package.json file.

Creating a package.json file

There are a couple of ways you can create your package.json file. You can run the ‘npm init’ command in your command line tool of choice, or you can use a tool called grunt-init, which is a handy project scaffolding tool that can build your whole project structure for you based on a project template. While, this is an awesome tool, we aren’t quite ready for that yet, so we are going to go with the easiest most straightforward way, which is copy and paste. I’ll head over to the Getting Started page on the Grunt website, and copy their package.json example. Now, I’ll paste it into a new document and save it as package.json in my project’s directory.

Now, let’s configure the file. First off, I want to point out that the file uses 2-space indents, and camelCasing. Personally, I prefer tabs, but it is always a good practice to use the coding standards established by the project. Since this is a Node Package Manager file, I will adopt their coding style. Both the name and version fields are required for Node Package Manager, and for Grunt to run, we will need to install the Grunt plugin along with any other dependencies by using the devDependencies field. Let’s change the name of our project to ‘hog-wild’. Notice the naming convention. You are not allowed to use non-url-safe characters, and your name can’t begin with a period or underscore character. The version value is a 3-number value that follows the Semantic Versioning Standard, which can be found at semver.org. The first number is the major version, the second number is the minor version, and the final number is the patch version. Right now, we have a major version of 0, which is what is used for initial development. Since, we don’t have a working app yet, this is a good version value to start off with.

You’ll notice that the devDependencies value is an object, which has it’s own key:value pairs. The keys are the names of the Grunt plugins we need to install, and the values are the plugin versions we need to install. Notice there is a tilde character in front of the versions. This means, that Node Package Manager should install the newest version of the plugin, all the way up to the next major revision range. So, for example, Node Package Manager will install the newest version of Grunt 0.4. So, if version 0.4.8 is the newest version, then it will download that. However, it will not jump to the next revision range. In other words, it will not install Grunt 0.5.0, because that might not be completely backwards compatible with your project and could break functionality.

For now, don’t worry about the devDependencies section. I will show you how to create your own devDependencies object later on as we work with Grunt. I do want to point out that this is a bare minimum example of a package.json file. If you take a look at the package.json file for my MikeMcLin.net website, you’ll see several other values. You can learn more about the various options you can add, by heading to the Node Package Manager package.json webpage. For now, let’s move on to the Gruntfile.js.

Creating a Gruntfile.js

Similar to the package.json file, the Gruntfile can be created in a few different ways. Since we are just starting out, I’ll copy the sample Gruntfile that is on the Grunt website. Now, I’ll paste it into a new file and save it as Gruntfile.js, in my project’s root directory, right next to my package.json file. Also, notice that it shares a similar coding style with Node Package Manager, like 2-space indents and so on, so we’ll continue to build this file using those same coding styles.

The Gruntfile wrapper function

First thing you’ll notice is the wrapper function. All the code goes inside of this function. This is boilerplate markup that never changes. You don’t really need to understand what is going on here to use Grunt.

Inside of the wrapper function there are 3 main sections. The first is your configuration, which is the meat and potatoes of your Grunt file. The next section is where you load the plugins that are required for your Grunt tasks, and the final section is for your task lists.

Setting up the Gruntfile.js config

OK, let’s jump into the config, to see what is going on. I’m going to remove a lot of these task configurations, so the config doesn’t look so overwhelming. The first thing you’ll see is a pkg property which is storing the contents of our package.json file. Once again, this is pretty much boilerplate stuff, you will probably never change this, and therefore all you need to know is that it is loading in the contents of your package.json file, and storing the data into the pkg parameter.

Now, we get to our first task, which is the concat task, which takes multiple files and joins them into one file. Inside the task, we have an optional options property, that can override some of the defaults for that task. Beneath that we have what is called a target. This task only has one target configured, but you can create multiple targets. We can name our target whatever we want as long as it’s a valid JavaScript identifier. Just stick with camel case target names, and you should be alright.

Target’s can also have their own options parameter, which will override the task’s options parameter. Inside of the target we are declaring some files. Since most of Grunt’s tasks are file related, understanding how to configure your files is very important. There are several ways you can tell Grunt which files you want to use. This method is called the Compact Format. It is best suited for read-only tasks that don’t have a destination file, like linting. This particular concat task is setup to grab all of the JavaScript files within the src directory and any of it’s subdirectories. In other words, it grabs what is set in the src parameter, and then performs it’s operation, which in this case is to concatenate all of the files. After concatenation, it needs a place to store the new file, which is set in the dest parameter, which is short for destination. In this case, the dest value is using a template to help name the file. We’ll go over templates in a bit. So, the issue is, what if we want to grab a different group of files and concatenate them as well? Well, you could create another target, however targets are usually used to divide tasks so that they can be run individually in different circumstances. Now we are seeing the limitations of the Compact Format. Let’s upgrade this to what is called the Files Object Format.
Now, we use the dest as the key, and the src as the value. We can easily add more file mappings while separating them with a comma.

While this works well, there is also another format called the Files Array Format, which seems to be more popular and flexible. This is the format I choose for the majority of my file-based tasks.

Using globbing patterns to specify files in your Gruntfile.js

Now that we know how to format our src and dest parameters, let’s take a look at how we can use globbing patterns to specify the files we want to use.

The first example is the most basic. You can simply type out the relative path to the file. Note that all paths are relative to the Grunt file.

The second example is an array of files. It will include those three files.

The third uses an asterisk wildcard which means any character except the slash character. So this would include the three files mentioned in the previous example, plus any other JavaScript file that is in the foo directory that begins with ‘th’.

Now, what if the foo directory has subdirectories in it? Well, those files will not be included. So, how do we include those? Well, we can use a double-asterisk, which will now look for JavaScript files in all of foo’s subdirectories, and their subdirectories and so on.

We also have a single node-glob pattern which I rarely use, but it’s there if you need it. You basically can create a comma-separated list of values inside of curly braces, and it will go through each entry as if it were it’s own.

It is important to note that the order that you place your files into an array matters. In the second example, the concatenated file would have this.js, followed by that.js and then the-other.js. This is really important when certain files require others to be loaded before they are. A good example would be a jQuery plugin needs to be loaded after jQuery has loaded. Whenever you use an asterisk, it loads the files in alphabetical order. If a file needs to be loaded prior to the other files, you can do so by putting it before the wildcard files in the array.

One of the most powerful tools is removing files from an array. You do that by prepending an exclamation point to the front of the filepath. This example will load in all JavaScript files in the foo directory, except for the bar.js file. This is also a handy way to load a file last. You can add all of the files using the asterisk, then remove the file, and now re-add the file and it will be added to the end.

Using templates in your Gruntfile.js

Finally, the last thing I want to talk about when discussing file paths is templates. Nearly everything in the Grunt config can be used as a template, which feels very similar to a variable. Templates follow the following format using less than and greater than characters and percent characters as delimiters. We’ve already seen a template earlier in our Grunt file. The dest for our concat task is using a template to set the destination file name. In this case, it is going to assign the value of the name parameter in the pkg object. Well, we are reading the contents of the package.json file, and storing it into the pkg object. So, essentially the pkg object contains the same data as the package.json object. So, the pkg.name value is ‘hog-wild’, since that’s the value we gave the name property in our package.json file.

Alternatively, we could use the separator property as a template if we wanted. If we changed this to concat.options.separator, the filename would now be semi-colon. Of course, this example isn’t realistic, but I just wanted to point out that nearly everything in the config can be used as a template. Templates will eventually be one of your best friends, and we’ll be using them a lot throughout this video series.

Gruntfile.js Plugins Configuration

OK, that’s it for the config object. I’m going to wrap the remaining parts of the Gruntfile up pretty quickly. As mentioned earlier, these are the Grunt plugins that we require to run our tasks. Since, we’ve deleted a good amount of our config section, we now are only left with the concat task. Therefore, this is the only task that we will need to load. So, how do we know what plugins are available to us? Well, you would head to the Grunt website and browse their plugins section. I will be picking out various plugins and installing them throughout this course, so don’t worry if none of this makes much sense to you right now, or seems overwhelming. It is actually very easy.

Creating Task Lists in your Gruntfile

Finally, the task lists… These tell Grunt which tasks to run, and in which order. This Grunt file has 2 task lists. The first one is named ‘test’. The test class will run the jshint task, followed by the qunit task. Obviously we’ve removed those tasks from our config, so this task would no longer work. The second task list is called default, and it is…well, the default task list.

So, how do we run these tasks lists. Well we run them using the command line. I would navigate to my project’s folder. Then, if we type the grunt command, like I did in the first video, the default task will run. If I want to run a specific task, I will type the grunt command plus a space, and then the name of the task list I want to run. For example, in this file, I might want to run the test task list, so I would type the command ‘grunt test’.

OK, that’s it for this video. If you are somewhat confused, don’t worry. The hard part is definitely behind you. This was a lot to take in, and it’ll all start making sense when we begin building real-life examples. Speaking of which, that’s what we’ll do in the next video, where we’ll look at how to concatenate and minify our JavaScript files.

View Transcript

Related Links

Grunt Task Runner
http://gruntjs.com
Semantic Versioning Specification
http://semver.org
NPM | package.json
https://npmjs.org/doc/json.html

More posts from the 2-part series: Goin Hog Wild with Grunt

  1. Introducing and Installing Grunt Task Runner
  2. Configuring the package.json and Gruntfile.js files
  • http://jitendravyas.com/ Jitendra Vyas

    Best video on Grunt on web

    • Mike McLin

      Thanks, I appreciate it. Working on the follow-up videos right now…

      • http://jitendravyas.com/ Jitendra Vyas

        I’m waiting

  • Berklie

    Seriously, fantastic walk-throughs… clear and concise. The care taken to highlight illustrative code is impressive.

  • http://coryg89.github.io/ Cory Gross

    Absolutely fantastic video tutorial. I wish I could make videos where I sounded so clear, understandable, and incredibly steady. I always feel like mine sound nothing like me and aren’t nearly of the quality it would be if I explained something in person. Can’t wait to check out the next one. I’m just now trying to figure Grunt out for use in future projects.

  • Luke Watts

    I wish I’d found this series two days ago. Spent most the time reading every single page of the grunt site and github repo and then back and forth. I couldn’t understand why a Task automation tool doesn’t automate the process of creating the Gruntfile. Finally got grunt-init set up and now I finally get it. Tomorrow…setting up the livereload / connect…

  • Alexander Perez

    These videos are so well done. What program do you use for your presentations?

  • statical

    Excellent walkthrough – thank you.

  • Anton

    Awesome Vids!

  • Hans Schenker

    Hi Mike ,
    congratulations for the detailled videos on grunt!
    Make the course:”Going Hog Wild with Grunt” come true!!!

  • Alper

    Clear, concise info with great visualizations. Thanks for taking the time.

  • Yordis Prieto

    Greaaaaaaat this video I can not lose :D

  • vsatyarthi

    really you got the best way to explain. waiting for the next video…

  • http://www.iamshanikhan.com Fahim Shani

    Grunt was very scary to me. but great video to get hand dirty.. waiting for the next video

  • apsuhos

    Why didn’t you complete the series??!! Your videos are excellent!

    Anyway, I am sure you had your reasons :) Keep up the good work..