Why linting Javascript is totally bloody useless
November 1, 2011 at 9:12 pm 7 comments
There was a post this week that was talked about how a missing “var” ruined their launch (because it put the Javascript variable in the global/module scope). All of the discussion about this seemed to focus on one thing “You Should Have Run jslint”.
I’m here to tell you that jslint (and the fork: jshint) is absolutely bloody useless, and hence I don’t use it.
Let’s have a quick look shall we. First let’s install jshint (which is better than jslint, and more modern):
$ sudo npm -g install jshint Password: /usr/local/bin/jshint -> /usr/local/lib/node_modules/jshint/bin/hint jshint@0.5.2 /usr/local/lib/node_modules/jshint ├── argsparser@0.0.6 └── minimatch@0.0.4
That all went well… So lets try it on haraka.js:
$ jshint haraka.js haraka.js: line 3, col 1, Use the function form of "use strict". haraka.js: line 5, col 14, 'require' is not defined. haraka.js: line 8, col 1, 'process' is not defined. haraka.js: line 8, col 22, 'process' is not defined. haraka.js: line 10, col 5, 'require' is not defined. haraka.js: line 10, col 34, 'process' is not defined. haraka.js: line 13, col 5, 'process' is not defined. haraka.js: line 13, col 46, 'process' is not defined. haraka.js: line 16, col 14, 'require' is not defined. haraka.js: line 17, col 14, 'require' is not defined. haraka.js: line 18, col 14, 'require' is not defined. haraka.js: line 20, col 1, 'exports' is not defined. haraka.js: line 21, col 35, '__dirname' is not defined. haraka.js: line 24, col 1, 'process' is not defined. haraka.js: line 34, col 5, 'process' is not defined. haraka.js: line 37, col 52, 'exports' is not defined. 16 errors
WTF? This script is pretty battle tested. Everything it has complained about are node.js variables, but everything I have read told me that jshint was node.js compatible.
So maybe jshint just shouldn’t be used. Let’s do a search on NPM for alternatives:
lint This package provide lint validation library + node-lint command line tool allows you to che
Looks promising. Installed it, tried it:
$ node-lint haraka.js
node.js:134
throw e; // process.nextTick error, or 'error' event on first tick
^
Error: Cannot find module 'vows'
at Function._resolveFilename (module.js:320:11)
at Function._load (module.js:266:25)
at require (module.js:348:19)
at Object.<anonymous> (/usr/local/lib/node_modules/lint/lib/lint/vows.js:5:12)
at Module._compile (module.js:404:26)
at Object..js (module.js:410:10)
at Module.load (module.js:336:31)
at Function._load (module.js:297:12)
at require (module.js:348:19)
at Object.<anonymous> (/usr/local/lib/node_modules/lint/lib/lint/index.js:15:16)
Fucking useless. And dependencies really aren’t that hard in npm. Let’s press on:
nodelint The nodelint command line tool allows you to check for problems using JSLint. You can specif
What do we get:
$ nodelint haraka.js 0 errors
Praise Thor! OK so now we’re getting somewhere. Let’s move on to another file:
$ nodelint utils.js
utils.js, line 5, character 78: Use the array literal notation [].
var CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
utils.js, line 9, character 10: Move 'var' declarations to the top of the function.
for (var i = 0; i < 36; i++) {
utils.js, line 9, character 10: Stopping. (10% scanned).
3 errors
These kinds of errors are completely fucking unreasonable, and laid down by Crockford who clearly needs to revise his viewpoint – putting the var in the for() statement is a reasonable thing to do, and yes I KNOW it doesn’t do what it looks like it does. I don’t care. And the problem is that these aren’t configurable checks for jslint – the “var at the top of the function” is not a parameter in the jslint config, and if it finds too many of those it just stops until you fix them!
So does nodelint actually find anything worth worrying about?
The truth is, yes it does occasionally find some issues, but getting it to accept your style is hard. Getting it to find real bugs is really hard. I’d love to be proved otherwise.
Entry filed under: Uncategorized. Tags: .
1.
Anton Kovalyov | November 6, 2011 at 2:13 pm
In case of JSHint I suppose you use global strict mode (which can be dangerous for client side scripts) and Node global variables. Now, linters are not magic—they can’t magically recognize that you want to use your script in a NodeJS environment so you simply had to set the node and globalstrict options. It would take you less time than writing this angry blog post.
Anton
2.
baudehlo | November 6, 2011 at 6:13 pm
All I did was install it via npm. If I’m doing that then I’m using node.js and thus I expect it to just work. Sorry if my expectations are unfair, but that’s how the world works. And no, it would not take me less time than that blog post – where is the documentation for that option?
$ jshint --helpUsage: jshint path path2 [options]
Options:
--version display package version
--config custom config file
--reporter custom reporter
--jslint-reporter use a jslint compatible xml reporter
--show-non-errors show additional data generated by jshint
3.
Anton Kovalyov | November 7, 2011 at 12:32 am
Good point about options docs on –help, thanks. I will let the guy who maintains the NPM package know.
That said, the statement “I installed it with NPM therefore I use it to check JavaScript in Node environment” is not unfair it is complete nonsense, sorry. I use our NPM package and I use it to automatically test client-side JavaScript before each commit. Other people use NPM package simply because it is the easiest way to check their JavaScript for mistakes and typos. (The other easy way is jshint.com but that requires copying and pasting)
But I feel like you just want to be angry. Be angry then—bye!
4.
baudehlo | November 7, 2011 at 2:10 am
Dude, seriously stop saying I’m angry or your comments will be deleted. Frustrated, sure, because linting JavaScript is way over sold as a solution to all problems that don’t show up until runtime.
But yes I’m sorry if an app that you install by first installing node, and then installing npm, doesn’t by default lint perfectly valid node code, then it is broken. At the very least it should provide a command line flag.
5.
James | February 3, 2012 at 7:56 pm
I agree with your thought that these jslint-type programs are useless if they can’t be configured.
Coming from perl, I love Perl::Critic and perltidy. But perlcritic is super ultra configurable, and therefore it only catches the problems that I really care about. I wish someone with better skills than I would write jscritic.
6.
baudehlo | February 9, 2012 at 7:55 pm
I agree – I’d like a version that I can enable/disable features much more easily.
7.
Liam (@networkimprov) | February 17, 2012 at 9:26 pm
See also the Node package: tools/closure_linter/