DLG Software


Application development

  with JavaScript, Flex, and AIR


This describes a "quick start" process for setting up Grunt to lint your code using its jsHint plugin.

Head's Up: this post from 2015 is still valid and Grunt is a great tool, but if you're just getting started with build tools you should also take a look at Gulp.

What is Grunt?

Grunt logo

Grunt is a task runner. That is, it executes tasks you might normally execute via a script or run from the command line — tasks like concatenating your files, minifying them, linting them, running unit tests, etc. Grunt's purpose is to help you automate these tasks, eliminating some of the time-consuming and error-prone work of JavaScript development (i.e., it does the grunt work for you).


One big advantage of Grunt is that it provides consistency and reproducibility. The tools you use and their versions are stored in metadata which is used for all installs. And Grunt uses the configuration and options you define in a simple JavaScript file for each execution. This ensures that a task or set of tasks always uses the same process with the same tools (and tool versions) with the same options.


Another benefit of Grunt derives from its wide acceptance in the jsdev community. Partly this is because of its use of JavaScript (and Node) and partly this is because it's just a smart, useful tool. In any case, its popularity has resulted in many Grunt plugins being available — for jsHint, Sass, Coffeescript, Handlebars, qUnit, and many more (full list here). All of this means that the use of Grunt can translate into a simpler and faster development process.


I'm not going to spend any more time describing Grunt here, there are plenty of posts that cover its uses and its usefulness (see Resources section below for some of these). This post assumes you're ready to get started using Grunt. The focus here will be on getting you up and running with Grunt so you can simplify a basic JavaScript applications development task — linting your code for potential problems. For linting we'll use jsHint.


What is jsHint?

Probably you already use jsHint to ensure code quality, but in case you don't here's the PowerPoint summary:

  • jsHint is a tool that checks JavaScript code for errors and potential problems. It can't do as much for you as a compiler running against strongly typed code, but it can help you avoid some basic mistakes
  • unlike jsLint it offers a great deal of flexibility in configuration — in many cases you can use configuration options to define what's valid code and what generates a warning or error
  • jsHint can help enforce code standards — your team can decide on what the standards are, codify these through jsHint options, and then implement a build process that only pushes code that's lint-free
  • jsHint can be run interactively. Go to the main jsHint page and just paste in your code. It will respond with a basic code analysis and a list of warnings and errors
  • interactive mode is nice, but JavaScript applications with more than a few files can benefit from running jsHint as a local process that scans an entire directory tree and output the scan results as a file
  • the jsHint Grunt plugin can be run on demand from the command line or as one step in a more comprehensive, controlled, reproducible build/deploy process

BTW, while jshint is an incredibly useful (some would say essential) tool don't get overconfident if your code passes its validation. Always keep in mind: lint-free code isn't necessarily efficient code.


For general info see the About jsHint page, and here is their docs page with configuration options. For info on the jsHint plugin for Grunt see its github page.


The remainder of this post is a "quick start" guide. If you get stuck and want more detail check out Grunt's Getting Started page or this very useful in-depth YouTube video: "Grunt JavaScript Automation for the Lazy Developer". For more detailed installation notes for the Grunt jsHint plugin see this post or this one.


Quick/basic installation of Grunt and its jsHint plugin

What follows is a walk-through of a basic installation of Grunt and its jsHint plugin. At the end of this you'll be able to run jsHint on a project's .js files with a simple Grunt command and send the results output to a file as XML.

Grunt installation/configuration background

Grunt is a Node.js module. That means to use Grunt you'll need Node installed (stable version 0.8.0 or later). You'll use the Node Package Manager (npm) to install the Grunt module and its jsHint plugin.


Grunt has two parts which we'll install in this quick start:

Grunt command line interface (grunt-cli): This lets you execute Grunt commands. Installed only once, installed globally

Grunt instance in your project: This is what actually runs the tasks. Installed at the project level (so, you'll have one Grunt instance for each project that uses Grunt).


Configuring Grunt involves creation of 2 project-level files:

package.json: metadata on your project. Used by Node package manager. Metadata includes project name/description/version, the node modules your project uses (i.e., its dependencies), the specific versions of those modules.

gruntfile.js: a file containing a javascript wrapper function that tells Grunt what it should do for your project (which processes to run, options for those processes). This is what Grunt will look for when you run the grunt command.

Installation steps

  1. Install Node if you don't already have it. Grunt is a Node module, so if you don't already have Node installed you'll need to start with that. Nowadays this should be quick and painless, just go to the Node main page and choose the install option. Note that Node's installation process includes the Node Package Manager, or npm. Note: on Macs you may need to use sudo to execute this install and to execute other commands mentioned here
  2. Verify npm is working. Once the Node installation is complete you can validate that npm is ready for use with a command like npm help (displays a list of npm commands in your command window) or npm faq (opens the FAQ in your browser)
  3. Install the Grunt command line interface (CLI). Once Node is installed you can start installing Grunt. First you need to install the Grunt command line interface. You will do this globally, but note that only the CLI is installed globally (instances of Grunt itself are installed at the project level). To install the CLI globally execute: npm install -g grunt-cli. The –g option is the option parm for global installation. Important: the CLI is a one-time install, you do NOT do this per project.
  4. Verify that the Grunt CLI is working. When the command has completed execution you can check if Grunt is ready for use by executing (note the double dashes here): grunt ‑‑version
    Once the Grunt CLI is ready you can start installing Grunt in a project. As noted above, Grunt instances are created in your project, not globally. While this takes a bit more disk space it has the enormous advantage of allowing different versions of Grunt for different projects. The version of Grunt used by each project will be recorded in the Grunt project metadata (package.json). Having this in metadata avoids any version confusion if you share this project with others.
  5. Create a package.json in your project. To install Grunt in a project move to the root directory of the project where you want to use Grunt. The first thing you want to do is create that metadata file, package.json. You could just create it "manually" — that is, create a text file named package.json and then paste in the text shown below. However, these steps will use the npm init command to create a basic package.json.
    The npm init command prompts you for info on your project, providing intelligent defaults as needed, then creates the file for you. So, in your project's root dir execute: npm init . Answer the prompts to create your package.json file. For this simple setup you can accept defaults for everything. You can provide a git repository if you want, but it isn't necessary (though leaving this field blank will generate some warnings when you do installs).
  6. Verify and optionally clean up your package.json. Now open your package.json in an editor.  It should look something like this:
     {
      "name": "gruntTest",
      "version": "0.0.0",
      "description": "first use of grunt",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "author": "your-name<your name>",
      "license": "BSD"
    }
    To keep things clean for this test setup you might want to edit the resulting JSON and delete some fields. For this test you can delete the fields main, license, and scripts. So, the final file after cleanup might look something like this:
    {
      "name": "gruntTest",
      "version": "0.0.0",
      "description": "first use of grunt",
      "author": "Joe Smith"
    }
  7. Install Grunt. Ok, now that we have the file Node will use to store project info we can install our Grunt instance in the project. From the project root dir execute: npm install grunt ‑‑save-dev (again, note those double dashes before the save-dev option). The save-dev option adds grunt to the project devDependencies metadata.
    Head's Up: if you do an npm install without the -–save-dev option (or -–save) your module will be installed BUT the module and version won't be recorded in your package.json file as a dependency (generally not what you want)
  8. Verify that the Grunt install succeeded. If all went well your project should have a new subdirectory /node_modules which itself has a subdirectory /grunt. Also, in your package.json you should now have an dependency entry for Grunt (the result of using that ‑‑save-dev). For example:
    "devDependencies": {
        "grunt": "~0.4.1",
      }
  9. Install jsHint. Getting jsHint is easy, it's just another Node module. This time execute:
    npm install grunt-contrib-jshint ‑‑save-dev . The result should be another new subdirectory (/grunt-contrib-jshint) and package.json should have another dependency entry (e.g., "grunt-contrib-jshint": "~0.7.1")
  10. Create your gruntfile.js. We're almost done. Now we'll create a gruntfile.js in the project dir. This file contains your instructions for Grunt — i.e., it tells Grunt what to do and how to do it. Below is a sample you can use for this installation. Just paste the contents into a file named gruntfile.js in your project root directory. NOTE: the options shown here are just examples, you'll want to specify the jsHint options that work best for your project/team.
    module.exports = function(grunt) {
    
      // The assignment below is NOT part of a normal gruntfile.
      // It just lets you introduce a problem for jsHint to find.
      // To have jsHint generate a warning about this file
      // just whack the semicolon in the assignment below.
      var dummyVar = "kill the semicolon to trigger jsHint warning" ;
    
      // Project configuration
      grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        jshint: {
    
          // Example 1: this spec lints this gruntfile. Delete semicolon
          // in dummyVar assignment above to have jsHint report a warning
          src: [ 'gruntfile.js' ],
    
          // Example 2: this shows the wildcard usage. This specification
          // will lint all .js files in /js AND all of its subdirectories
          // src: [ 'js/**/*.js'],
    
          // Example 3: this targets a specific dir but not its subdirs
          // src: [ 'js/views/*.js'],
    
          // NOTE: you can exclude dirs using ignores option (see below)
    
          options: {
            eqeqeq: true ,
            smarttabs:true ,
            laxcomma:true ,
            laxbreak:true ,
            // Reporter options control output to file
            // reporter: 'jslint' ,
            reporter:'checkstyle' ,
            reporterOutput: 'jshint.xml' ,
    
            // files in js/libs and its subdirs will NOT be scanned
            ignores: [ 'js/libs/**/*.js'] ,
    
            // use this option with care
            // force:true
          }
        }
      });
    
      // Load the plugin for the jsHint task
      grunt.loadNpmTasks('grunt-contrib-jshint');
    
      // Default task(s) run on grunt command with no parms
      grunt.registerTask('default', ['jshint']);
    };
  11. Lint your code. Ok, at this point we're ready to lint. From any project dir execute the grunt command. This command with no parms will run the default task(s) you've specified in gruntfile.js. Note that you can run the grunt command from any project dir because Grunt will search up the tree to find your gruntilfe.js. You can also "manually" run a specific task by passing it as a grunt command parameter, for example grunt jshint. See the Grunt site for more info on command options.
  12. Check that output file jshint.xml. If jsHint found no problems then the contents of jshint.xml will be a simple XML shell with no warnings or errors. If it does report warning or errors then correct the problems or set your jsHint options to suppress warnings as required by your project (options for this listed on the jsHint options page, and here is a good site explaining some of those warning and error messages in a bit more detail).

This post has kept things simple in order to get you up and running quickly. However, there is lots more to Grunt (and jsHint). For example, Grunt has a watch plugin which can run a process whenever a file changes (so, using watch you could auto-run a jsHint scan on files whenever they're saved). For more detailed info on Grunt see the resources below. Hopefully you'll find that Grunt and its many plugins speed and simplify your development process.

 

Resources


Flex/AIR certification logo
About

JavaScript

JavaScript appdev primers

General JavaScript

SPA Demo Application

Backbone Demo Application

Recommended sites

Flex/AIR

Flex/AIR primers

Flex demo apps

all require Flash Player!

AIR mobile dev

SAS

SAS Introduction

Varia

About

Archives