Tightening Jshint

Measuring and increasing number of jshint settings.

A typical software project goes through multiple phases and iterations. It starts as an idea, maybe involves some planning, then the development begins. The features are added, tests are created, users and stakeholders are consulted. If initial iteration is successful, more customers appear, asking for features, fixes, and integration with other software pieces.

The project is in the flux at first: things are being prototyped, tests (if they exists) are sparse; the main focus is on implementing the right functionality. Later, as first features are solidified, the developers need to worry about not breaking the as new things are added. Regression tests become necessary, and features are described more formally.

Jshint

Jshint is an excellent sanity check tool for JavaScript. Initially, just a clone of Jslint, it quickly became the goto static analysis tool, catching misspelled variables, stray brackets and such.

Most projects I see use Jshint settings stored in a separate JSON file, usually called .jshintrc in the project's root folder. Multiple tools can load this file and run Jshint on the source code: editors, command line tools, grunt build tool. The latest version of jshint allows more than 60 static checks specified using .jshintrc.

At the project's start we might specify pretty lenient settings, planning to tighten the checks later. For example, since we might not agree on the types passed around, we might use truthy equality == to compare variables. Later we would switch to more robust triple equal === operator that does not perform type casting. So the jshint would start with:

"eqeqeq": false  // do not require ===, allow ==

and later start checking for more robust comparison

"eqeqeq": true  // require === for comparison

Problem

The project matures, but no one takes a second look at the Jshint settings file, tightening the screws! So the settings that are supposed to help us catch regressions are never switched on.

Jshint-solid

I wrote jshint-solid to measure and warn when the project's Jshint settings are too permissive. The warnings can be ignored at the early stages, but as you start releasing the software to customers, you might heed the warnings and start flipping more switches, progressively making decisions about software principles, allowed language features and environment variables.

The exact values set in .jshintrc file are not checked at this point, the fact that the team actually decided on an option is the important fact. Later I plan to look at the individual options to warn about bad software practices, for example to warn that the setting boss (tolerate assignments where comparisons would be expected) is set to true.

Installation and use

Requires nodejs. Install jshint-solid as the global command line tool.

npm install -g jshint-solid

Go inside the folder were .jshintrc is located and call

jshint-solid
// shows results

You can pass .jshintrc path as first argument

jshint-solid /projects/foo/.jshintrc

The tool prints the percentage of all possible jshint settings specified inside the file:

// typical run
$ jshint-solid
jshint ./.jshintrc covers 14% of all possible settings
see all possible settings at
https://raw.github.com/jshint/jshint/master/examples/.jshintrc

The exact coverage thresholds are up to the team. I suggest using very low number initially, but during the first "maturation" step, increase the threshold to 40-50%. Before releasing the software to external customers, you might want to tighten even more and set the majority of switches.

It is very simple to decide on most of the settings, even initially, Jshint has a lot of target environment settings, for example for a nodejs application one could easily set 12 options:

"browser"       : false,    // Web Browser (window, document, etc)
"couch"         : false,    // CouchDB
"devel"         : true,     // Development/debugging (alert, confirm, etc)
"dojo"          : false,    // Dojo Toolkit
"jquery"        : false,    // jQuery
"mootools"      : false,    // MooTools
"node"          : true,     // Node.js
"nonstandard"   : false,    // Widely adopted globals (escape, unescape, etc)
"prototypejs"   : false,    // Prototype and Scriptaculous
"rhino"         : false,    // Rhino
"worker"        : false,    // Web Workers
"wsh"           : false,    // Windows Scripting Host
"yui"           : false,    // Yahoo User Interface

Feedback

Let me know if jshint-solid is useful by twitting @bahmutov. If you find a problem, please open an issue at github and it will be resolved.