This post is part 2 of 2 in the series Goin Hog Wild with Grunt
- Introducing and Installing Grunt Task Runner
- Configuring the package.json and Gruntfile.js files
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 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.
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.
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’.