Javascript Linting Tool Evaluation

In our internal JavaScript ‘User Group’ (called JS-Posse in honour of the legendary ‘The Java Posse‘ by Dick Wall, Chet Haase et al.), we recently decided to evaluate alternatives to our current JavaScript linting standart, JSHint. Although well established by now among different development teams across synyx, using it never felt 100% comfortable. A quick Google search left us with three alternatives:

…as well as JSHint itself, of course.

We drew up a quick spreadsheet for evaluating the tools and came up with the following.

Criteria

  • Performance How long does it take to run over our example project, a single page webapp with a couple of thousands of JavaScript LOC?
  • Licensing Does the license meet our requirements (and those of our customers, of course)?
  • Project health/adoption How healthy is the project? Is it on Github, and is it well maintained?
  • Completeness of configurations Does the tool cover all our use-cases for a linting tool?
  • Productivity (rule set creation / project setup) When creating a new project, is it difficult to create a matching ruleset? Does the tool come with a reasonable default rule set, or do you need to set up all the checks yourself?
  • Productivity (active software development) During active development, does the tool assist the developer in writing quality code, or does it bully you to the point where you’d rather abolish using a linting tool at all?
  • Quality of Documentation/Tutorials/Self Help How good is the project documentation? When the tool breaks the build with a certain error message, how difficult is it to find reliable information on the error in question (why does it occur, why is it a bad practice, how to fix it)?
  • Ability to integrate with existing projects Is it possible to integrate the linting tool in an existing projects without making changes to the project to comply to the rules?
  • Integration with build tool Is it possible to integrate the linting tool into your build chain to receive direct feedback?
  • ES6 support How well does the project support future versions of the language?
  • Pluggable Is it possible to extend the given rule set with custom checks?

JSHint

The first tool we looked at was the already-familiar JSHint. We already knew what was bothering us about it:

  • Its hard to find the documentation for a certain error message. While the error messages itself are mostly self-explanatory, it can be somewhat difficult to find out how to deactivate or customize a certain rule. For example, http://jshint.com/docs/options/ JSHint has both ‘enforcing’ and ‘relaxing’ rules. While setting a ‘enforcing’ rule to true turns it on, setting a ‘relaxing’ rule to true deactivates it.
  • More often than not, using JSHint can be frustrating. For example, we had ‘maxdepth’
    set to 3, meaning a maximum of three nested blocks of code was allowed. In case one of those blocks was a ‘for … in‘ statement, JSHint would (correctly) complain that its body should be wrapped in an ‘if(obj.hasOwnProperty(key))‘-check to filter out unwanted properties. However, doing so meant introducing another nested block, and if that pushed the total depth beyond ‘maxdepth‘, JSHint would fail the build. The solution was usually to introduce private helper functions, which can make otherwise trivial code difficult to read (since you have to skip blocks of code).

Of course, that is not really the fault of JSHint (seeing that it only did what it was told to do), but it was a rather big annoyance that caused us to re-evaluate our JavaScript linting practices in the first place.

  • Being a fork of JSLint, JSHint has the same license containing the infamous JSLint License ‘Good, not evil’ statement. While we understand its humorous intent (and being a fairly social responsible company, we wholeheartedly support it), we were worried that some corporate lawyer might not approve of our use of a tool bound to such a license.

JSLint

After JSHint we decided to evaluate the old guy in the gang, JSLint. It was the first linting tool for JavaScript, and it feels like that. From our opinion JSLint has two major problems, besides the license (see JSHint):

  • The website of JSLint is very old-school and does not contain any explanations of the ruleset or any information to get a link between the error messages provided by JSLint and the problem in the code. So you have to search through the internet to find any third-party explanation that will help you to fix the problem.
  • Some of the rules of JSLint are, at least, strangely named. There is a rule to forbid (or allow, if deactivated) ‘stupidity’. The project’s web page does not provide any explanation (again) – resorting to Google, we found out that ‘stupidity’ referred to the usage of synchronous functions in Node.js’s file system module.
  • The rule set is very strict and, when you look through the GitHub issues and pull requests, it is very hard to participate in the JSLint project. That’s why the community is very small and there are a lot more people active in JSHint and other projects and bring in their ideas there. Maybe that is why JSLint does not provide a rule similar to ‘latedef’ from JSHint or ‘no-use-before-define’ from ESLint. Without this rule it is very hard to structure your code with private named-functions at the end without assigning the function to a variable at the start (and that would not be what we want).

Closure Linter

The Closure Linter is part of Google’s Closure tool set. It was designed for internal use and provides very little options for customization. Since following the rules enforced by it seems to be mandatory within Google, that is certainly an acceptable practice. However, since it is (for example) not possible to change the default maximum line length of 80 characters, we quickly decided not to look into the tool any more.

ESLint

When looking at ESLint, we were quick to decide that we might be looking at a potential winner:

  • While the project is (by far) the youngest (or as others might put it: the least mature) of the four tools we looked at, it is also the best maintained. 100+ contributors on Github and a roughly monthly release schedule speak for themselves.
  • Applying it to our example web app, we were surprised to find out that it was sufficient to write about ten lines of configuration to perform the same amount of checks that required around a hundred lines in JSHint. Of course, that might only mean that we have the same idea of quality JavaScript code as the tool’s authors, but nevertheless it meant that the tool would be quite easy to adopt into our development process.
  • The output is quite handy: It prints both a one-line human readable error message as well as an error code for a quick lookup in the documentation.

Evaluation

The criteria from above has been weighted from five to 15, from not important to important, and the tools got a 0, 0.5 or 1 if it does not, almost or absolute fulfill the criterion.

jsLinting

Conclusion

As you can see in the image above, ESLint proved to be the winner of our evaluation. We decided that its major flaw, the potential immaturity, was acceptable to us since by its nature, it would only be used during (internal) development. The ease of use, both because of the robust and reasonable default rule set and the high-quality documentation, outweighed any concern by far. We are looking forward to adopt ESLint into our development tool chain over the coming weeks and months!

Kommentare

  1. facebooks flow seems interesting, too
    <a href="http://flowtype.org/" title="flowtype" rel="nofollow">http://flowtype.org/</a>