A Comparison of JavaScript Linting Tools

article

#2

Jslint:
"The official website is not very helpful, for example it lacks any information on how to integrate it with your editor."

I can find zero information on any of the sites about integration with my editor (netbeans).
Jslint on the other hand, works just fine with netbeans.
Just add it in the plugin-settings.
No trace of the other ones there.


#3

I prefer JSLint myself too because it knows what it wants. There's no letting things slide, or forgiving forgotten semicolons with jslint. It will make you cry, and make you a better coder in the process.


#4

You can get the others to be as strict as JSLint too, but it's true they do require some configuration to get to that point


#5

Exactly, why mess about having to configure the others when JSLint is already configured for you by a JavaScript expert.


#6

Sure, if you agree with Douglas' setup. But there are plenty of JavaScript experts out there who have a different opinion. Who says JSLint's way is the only way?

As an example of why I think ESLint is great is their "handle callback err" rule. In NodeJS, it's important to handle error parameters in callbacks, and this rule can check whether or not that was done. You can't have this with JSLint at all.


#7

Nobody is saying that it's the only way. I am saying though that you can always make things less good, and I'm glad that jslint has the moral fortitude to stand up for correctness.

That sounds excellent. All we want now is someone that has done the work of creating an ESLint ruleset that matches JSLint's set of rules too.


#8

For sure. Something I like about JSCS is that they provide several alternative rulesets out of the box, so you can pick something that's close to what you like, and then customize it further. Perhaps someone could make a collection like that for ESLint too. Would definitely come in handy for not having to start from scratch.


#9

It shouldn't be a matter of what you like - the idea of any LINT is to detect any usage that may cause problems. One thing about JSLint is that all of the rules it uses are there to detect something that has been known to cause issues is scripts. Each rule has a corresponding example of a script that crashed because it didn't follow that rule.


#10

Not all of them have anything to do with issues. Examples of rules that are purely stylistic:

  • Use spaces for indentation, not tabs
  • White-space between parameters, function foo( a ) is not allowed, where function foo(a) is.

Although these can actually be disabled using the --white flag, who knows what else it does, since it's not documented anywhere.

But that defeats the purpose of not having to configure it, as you were saying. Plus, since JSLint doesn't have a configuration file, you have to remember to use the correct configuration flags whenever you run it.

As a fun factoid, the tabs vs spaces rule was silently added without warnings to JSLint. What if you had written your code in a certain way, and the next day it was decided that you no longer can do it like that? It seems a bit problematic to me. Especially as Douglas is saying new should not be used anymore, and many large codebases use it extensively. What happens if JSLint suddenly decides to not allow it anymore, just like it decided with tabs?


#11

Who knows what else? We can all know as the code provides us with the details. Doing a search for the word white reveals all.

Line numbers (after Chrome pretty-print)
155 - allowed options
242 - expected at column
258 - use spaces, not tabs
318 - unexpected character
1005 - expected space (one space)
1012 - expected space (one space only)
1019 - unexpected space (no space)
1026 - unexpected space (no space only)
1031 - missing space
1043 - no comma space then to 1026
1054 - no semicolon space then to 1026
2614 - expect case at same column as switch

The following code examples are poor code, to demonstrate the different JSLint white space warnings that are triggered within the code.

Expected x at column

var x = true;
 if (x) {
    x = false;
}

Use spaces, not tabs

var x = true;
if (x) {
	x = false;
}

Unexpected character (spaces on blank line)

var x = true;
    
if (x) {
    x = false;
}

Expected space

var x = true;
if(x) {
    x = false;
}

Expected only one space

function example() {
    "use strict";
    return  '';
}

Unexpected space

var a = ( 1 + 2);

Unexpected space where only none should be

var a = -[0 , 1];

Missing space

var x = true;
if (x){
    x = false;
}

Expect case at same column as switch

var expr = "Oranges",
    msg;
switch (expr) {
    case "Oranges":
        msg = "Oranges are $0.59 a pound.";
        break;
    case "Apples":
        msg = "Apples are $0.32 a pound.";
        break;
    default:
        msg = "Sorry, we are out of " + expr + ".";
}

Also, there's a handy jslinterrors site that can be handy too, which was only used to retrieve some suitable coding examples for common issues.

I don't know about you but I would learn about why tabs cause such as issue compared with spaces, and proceed to resolve the problem which can be easily and rapidly done across all code-bases with the right tools.


#12

The issue with tabs vs spaces is purely subjective. Dog people vs cat people. Vim vs Emacs. Same thing.


#13

Yes, it is subjective and you'll find that Crockford himself doesn't mind which is used either, as long as it's consistant.

The issue of tabs vs spaces only becomes a problem when you are coding with other developers, at which point there's an issue of change control among the code as developers fight like a pack of squabbling cats for control over the code base to set their own personal preference, and waste time converting everything back and forth.

As such, some sort of standard must be set for harmony to return, and it just so happens that the spaces side of the camp is seen to have less potential problems than tabs.

If you just so happen to prefer to indent using tabs, then clearly you will have problems with jslint.


#14

I don't agree but let's not derail this into a tabs vs spaces thing smile

Anyway, the point about the tabs rule and the white space around arguments rule was to show that not every rule in JSLint has an objective reason behind it. I think it's fine for a tool to set a default for such rules though, but in JSLint's case, it's not so easy to deactivate the rule because it doesn't have a configuration file.


#15

Every rule came about as a response to a widely-regarded issue. Are there any other rules on which you are puzzled about its objective nature? Perhaps we can shed some light for you on the rationale behind it.

What sort of config file did you have in mind?

my-special-jslint-config.js

/* jslint white:false */

#16

Well I didn't really see anything on what problems tabs cause, or what problems white space around argument names cause.

A global configuration. The example you give with the comment is local only to a single file, therefore not very practical in larger projects.


#17

One of the reasons is:

There are also issues in regard to a consistant layout, and that the default tab stop size is just too large. While it's possible for custom tab stops to be configured, it still doesn't help to provide consistency in other places.

I hope that you are not just being difficult now, and trust that you really are interested in some answers here.

Sublime Text for example has config files for jslint, both default ones and custom user config files too.

There are also jslint configs for when using grunt, and other systems that can be used to customise it for your build process.


#18

It depends on the editor you are using. The one I use has a configuration setting for how many spaces to convert tabs to. This means that regardless of whether I type spaces or use tabs the resultant files always contain spaces and never contain tabs.


#19

I can change tabstop to 2, 4, 8, anything, and the code will always indent the same. You only use tabs for indentation. If you follow a pattern where you use it only for indentation and nothing else, there is no problem.

What about the other case I mentioned?

Yeah that's true. I was referring to the lack of it in the tool itself, so you need another tool to complement it for something that others have out of the box. Of course you can always slap something else on top to fix things in many cases.

Considering the argumentation for JSLint seemed to be it doesn't require configuration, this seems to defeat it.


#20

On your particular setup it will indent the same. When your code is shared with other people, that's where problems can occur. What works well for you at a tab stop of 2 can be a big problem where someone else has a tab stop they can't change of 8.

The problems of working with other people can be hard to deal with, and commonly requires a solution of setting unreasonable standards.

I have no wish to misrepresent you, so please clarify which case that is that you mean.

You seem to be misunderstanding what's happening here, for we are not two Titans holding a grand debate. Instead, I am working on finding solutions and answers for you. So saying, what else can we help you with here?


#21

Here's a sample with tabstop 2:

function foo() {
  hello();

  if(foo) {
    bar();
  }
}

Here's a sample with tabstop 4:

function foo() {
    hello();

    if(foo) {
        bar();
    }
}

Here's a sample with tabstop 8

function foo() {
        hello();

        if(foo) {
                bar();
        }
}

I don't see the problem.

The second case was extra spaces around an argument name.