Lint your JavaScript with grunt and jshint

After I’ve introduced You to Yarn I will show You more client side tools in this post.

Grunt is a task runner which comes in handy for a lot of setup and configuring work e.g. concatenating and minimizing js or css files.

To get started You can add grunt via yarn to your project

yarn add grunt

Configuration

Grunt looks for a Gruntfile.js file in your root directory. Yes it is Gruntfile.js with a capital ‘G’. An empty

Linting with JShint

yarn add grunt-contrib-jshint
module.exports = function(grunt) {
  grunt.initConfig({
    jshint: {
      all: ['Gruntfile.js', '/js/*.js'],
      options: {
        globals: {
          jQuery: true
        }
      }
    }
  });
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.registerTask('lint', ['jshint']);
};

This configuration will print all findings directly onto the console which is nice for testing the script but when you burn down your lint issues a file comes in handy.

Configuring JSHint’s Output Format

To visualize the findings in Jenkins you can configure the checkstyle format. It produces a xml file which you can use inside Jenkins’ checkstyle plugin.

When You want to have a more human readable format you can generate an html report. Therefore You have to install the jshint-html-reporter:

yarn add jshint-html-reporter

and configure the JSHint task accordingly.

options: {
   reporter: require('jshint-html-reporter'),
   reporterOutput: 'jshint.html'
 },

You can have both configurations in one file

module.exports = function(grunt) {

  grunt.initConfig({
    jshint: {
      options: {
        globals: {
          jQuery: true
        }
      },
      src_files: ['Gruntfile.js', 'app/static/js/*.js'],
      local: {
        options: {
          reporter: require('jshint-html-reporter'),
          reporterOutput: 'jshint.html'
        },
        src: [ "<%= jshint.src_files %>" ]
      },
      jenkins: {
        options: {
            reporter: 'checkstyle',
            reporterOutput: 'jshint.xml'
        },
        src: [ "<%= jshint.src_files %>" ]
    }
    }
  });
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.registerTask('lint', ['jshint:jenkins']);
  grunt.registerTask('lint-local', ['jshint:local']);
};

 

Inefficient jQuery Selectors

My PyCharm IDE warns me if I use inefficient jQuery selectors:

As I am a bit nosy I wanted to know “how” inefficient these selectors are. So I compared the inefficient

$("#items tbody");

with the optimized

$("#items").find("tbody");

Here is the test code:

window.onload = function () {
    test("unoptimized", function () {
        for(var i = 0; i < 100000; i++){
            $("#items tbody");
        }
        assert(true, "Test finished");
    });
    test("optimized", function () {
        for(var i = 0; i < 100000; i++){
            $("#items").find("tbody");
        }
        assert(true, "Test finished");
    });
};

I used the little test framework from the book Adventures of the JavaScript Ninja

The results vary from run to run but the optimized version just takes around 55% of the time which makes it almost twice as fast. Though the single execution is in the nanosecond range, if you heavily rely on using jQuery, it might be worthwhile to optimize your selector statements.

Code on GitHub