Maintaining Consistent JavaScript with JSLint

By: James Allardice

Tags:

  • javascript
  • jslint

As you can probably imagine, the White Label Dating platform contains a lot of JavaScript. It’s been written by many people over many years, and when you have numerous people working on the same code you’re always likely to end up with a bit of a mess. The code may work as intended. It may even follow a lot of best practices and be easily extensible. But it almost certainly won’t be nice to look at, or easy to read, and that can often lead to problems with maintenance in the future.

In an attempt to make our JavaScript easier on the eye, we have started using Douglas Crockford’s JSLint tool to enforce a consistent style throughout. I’m sure you have your own opinions on JSLint, and I’m well aware that many developers (myself included) think that some of the rules that JSLint wants you to follow are verging on ridiculous (for example, forbidding the use of the ++ increment operator). However, by fine-tuning the various options available to you, and putting up with the occasional annoyance, you can use JSLint to your advantage and end up with a JavaScript code base that is much easier to maintain.

Configuring JSLint

We decided to configure JSLint on a per-file basis. This way, every file can have its own options which allows us a bit of flexibility. If you want to allow the use of the increment and decrement operators in a file, and you want common browser properties like document to appear predefined (JSLint will throw undefined errors if they don’t), you can do so with a jslint directive at the top of the code:

/*jslint plusplus: true, browser: true */

There are some JSLint options that allow you to get away with sloppy code formatting (such as the white option, which will allow “messy white space”). Unfortunately, there is no way to enforce that this option is always turned on, so we have to simply make developers aware that such options must not be set in any files. If they were, it would kind of defeat the point.

Enforcing the use of JSLint

Now that we’ve defined the standards for JavaScript development, we need a way to enforce them. It’s very easy to simply paste your JavaScript into the online tool at on the JSLint website, but that’s a bit too much work. Instead, we wanted to automate the process, and we have achieved this with a Git pre-commit hook, which prevents anyone from committing JavaScript that doesn’t pass JSLint when it should.

There’s a couple of things that are required for our hook to work. The first is Node.js (along with NPM, the Node Package Manager). Once you’ve got those up and running, you can globally install node-jslint which will add the executable to your path:

npm install -g jslint

Now we can run JSLint from the terminal, so we can get on with our Git hook. It will run JSLint against all JavaScript files staged for commit, and even provide colour-coded feedback. It needs to be placed in repository/.git/hooks/pre-commit:

#!/bin/sh

files=$(git diff --cached --name-only --diff-filter=ACM | grep ".js$")
if [ "$files" = "" ]; then 
    exit 0 
fi

pass=true

echo "\nValidating JavaScript:\n"

for file in ${files}; do
    result=$(jslint ${file} | grep "${file} is OK")
    if [ "$result" != "" ]; then
        echo "\t\033[32mJSLint Passed: ${file}\033[0m"
    else
        echo "\t\033[31mJSLint Failed: ${file}\033[0m"
        pass=false
    fi
done

echo "\nJavaScript validation complete\n"

if ! $pass; then
    echo "\033[41mCOMMIT FAILED:\033[0m Your commit contains files that should pass JSLint but do not. Please fix the JSLint errors and try again.\n"
    exit 1
else
    echo "\033[42mCOMMIT SUCCEEDED\033[0m\n"
fi

Keeping track of our hook

One of the problems with Git hooks is that they are not part of the repository itself (since they live within the .git directory). We don’t expect to be changing our hook regularly, but it would be nice to have the hook itself under version control. We achieved this by simply finding a suitable location in the repository, and creating the hook script there. When anyone sets up their development environment, a single command can be run to activate the hook, by symlinking to the hook file from the Git hooks directory:

ln -s /path/to/repo/pre-commit-jslint /path/to/repo/.git/hooks/pre-commit

In the near future we would like to get this step integrated into a more general “development environment setup” script, so that new starters or anyone setting up a clean dev environment can kick off one script and come back later to a fully working local copy of the app.


About the Author

James Allardice

James Allardice is a Senior JavaScript Developer at Venntro. He is passionate about clean, maintainable JavaScript and is regularly on the lookout for ways to improve the JavaScript development process. He's currently interested in JSHint, Grunt, AngularJS and ECMAScript6.