Thursday, December 26, 2013

jshint is good, but...

Let's just be upfront here because I don't want to hurt peoples feelings on jshint (which is apparently known for hurting people's feelings.) I can say many things about jshint , and 99% of them are good. In fact, there are a LOT of good practices that jshint enforces that I think are absolutely invaluable. Yet, here I am really just annoyed with a bunch of these "Code errors." Let me give you some examples.

1. I'm a NodeJS developer working on a test suite, using SHOULD and MOCHA, and I use jshint to test and make sure I use good coding practices. Here's what happens:

Expected an assignment or function call and instead saw an expression.
(x.should.be.a.Function;)
Expected an assignment or function call and instead saw an expression.
(x.should.be.a.Function;)
'require' is not defined.
'require' is not defined.
'describe' is not defined.
'describe' is not defined.
'it' is not defined.
'describe' is not defined.
'it' is not defined.
'describe' is not defined.
'it' is not defined.
'describe' is not defined.
'it' is not defined.
'describe' is not defined.
'it' is not defined.
'describe' is not defined.
'it' is not defined.
'it' is not defined.
view raw gistfile1.txt hosted with ❤ by GitHub

Well SCREW YOU TOO. Look at all these unmeaningful errors. I mean, require is definitely defined. I shouldn't have to deal with the jshint output like this.

2. I'm working on a token reader for the front end.

while(var token = tokenizer.readToken()){
}

Expected an identifier and instead saw 'var'.
Expected ')' to match '(' from line 7 and instead saw 'token'.
Expected an identifier and instead saw '='.
Expected an assignment or function call and instead saw an expression.
Missing semicolon.
Missing semicolon.
Expected an identifier and instead saw ')'.
Expected an assignment or function call and instead saw an expression.
Missing semicolon.
view raw JSLintOutput hosted with ❤ by GitHub

What happened here? I expected an assignment and a falsy check to occur during a while loop, and I got this lame output. Sure it's scrutiny and you can easily rewrite it to something like this:

var token;
while(true){
token = tokenizer.readToken();
if(typeof token === "undefined"){
break;
}
}

The question is "Why?". So some novice developer can come in and see what your code does faster? Chances are this small obscurity will teach the novice developer about javascript and the things you can do with it. Sure it's "cute" and silly, but is it really worth your time to change your coding style like this? Just document it.

// This loop reads the token and performs a falsy check
// to assert the token exists before performing the code
while(var token = tokenizer.readToken()){
}
view raw Documented.js hosted with ❤ by GitHub

See, that wasn't so hard. I'd rather teach the beginner the "rules" and then break them.

The following example kills me every time:

switch(true){
case true:
case false:
console.log("this is a test");
default:
}
view raw switch.js hosted with ❤ by GitHub

Expected a 'break' statement before 'default'.

What if I wanted it to bleed over into the cases and use spaghetti code? Apparently novice coders are too dumb to spend time and figure it out for themselves. Chances are if your code is more complicated, you wanted another statement anyway. Yet, what if the offending sample is simple? What if the code happens to be easier to write and read with the switch statement? That's a matter of your opinion and really the decision should be left up to you.

(It also told me console was not defined but that's arbitrary.)

Look, just make a decision for yourself and use jshint to let it find your bugs before you do. Just make sure you read the error and make a determination for yourself if it's worth "fixing."

I probably spend more time sifting through 'console' is not defined more often than I would personally like to.

~function(){console.log("Josh");}();

Expected an assignment or function call and instead saw an expression.
~function(){console.log("Josh");}();
'console' is not defined.
~function(){console.log("Josh");}();

No comments:

Post a Comment