JSHint 1.0.0 RC1

UPDATE: JSHint 1.0.0 RC3.


After three months and 100+ commits, JSHint 1.0.0 is ready for release. This is the biggest release for JSHint so far, and that's why I've decided to run it through a release candidate phase first. I tried my best to make it as backwards compatible as possible, but there might be a small number of incompatibilities depending on how you use JSHint. Please keep that in mind and test your integration before updating to 1.0.0.

One of the biggest changes is that node-jshint is now part of the main JSHint project, which means that there will no longer be lag time between releasing a new version and publishing it on NPM. Node and NPM is now the main and recommended way of using JSHint on all platforms. This also means that starting with "1.0.0", JSHint will start using the node-semver versioning system instead of the old rN system.

In addition, this version drops support for non-ES5 environments. This means that JavaScript engines that don't support the ES5 syntax will not even parse JSHint's source code. (For example, the online interface for JSHint will not work in older versions of IE.)

I'm very excited to finally release this version and I encourage everyone to try out the release candidate and report any bugs and issues you encounter. The full changelog is provided below, with examples and links to relevant issues.

Parser

This version has a completely rewritten lexer. Since it's no longer a giant regexp, the new lexer is more robust and easier to read. I'd like to thank the authors of Esprima and Traceur since I borrowed some pieces from them.

  • This version adds support for Unicode identifiers! (#301 and #716)

    var π = 3.1415;

  • Adds support for the comma operator. (#56) JSHint now parses code like the following (note the comma in the middle expression):

    for (var i = 0, ch; ch = channels[i], i < channels.length; i++) { // ... }

  • Improves support for numbers. JSHint now understands numbers with leading dots (e.g. .12) and doesn't generate false positives on invalid numbers (e.g. 099). In case of invalid numbers the parser still parses them but marks as malformed and generates a nice little warning.

  • Adds support for more relaxed JSHint directive syntax. JSHint now recognizes space between /* and jshint/global/etc. and allows you to use single-line comments for directives in addition to multi-line comments:

    Before: /jshint strict:true /

    Now: /jshint strict:true / / jshint strict:true / (note the space) //jshint strict:true // jshint strict:true

    One potentially breaking change is that all lists inside JSHint directives must be separated by commas from now on. So /*jshint strict:true undef:true */ won't fly anymore but /*jshint strict:true, undef:true */ will (note the comma).

  • Adds better parser for regular expressions. Previously, JSHint would check the grammar of regular expressions using its own internal logic. Now, JSHint compiles the parsed expressions using the native RegExp object to check for grammar errors.

  • Adds support for a defensive semicolon before [. (Ticket #487)

  • Adds support for unclosed multi-line strings and removes warnings about unnecessary escaping for \u and \x in strings. (#494)

Bug fixes:

  • Fixes a bug with JSHint not warning about reserved words being used as variable and function declaration identifiers. (Ticket #744)

  • Fixes a bug with JSHint generating a false positive Missing whitespace... warning on trailing commas. (#363)

  • Fixes a bug with JSHint not being able to parse regular expressions preceded by typeof (e.g. typeof /[a-z]/) and, in some cases, *=, /=, etc. (e.g. if (x /= 2) { ... }). (#657)

General

  • This version adds a unique numeric code to every warning and error message produced by JSHint. That means that you can now ignore any warning produced by JSHint even when there is no corresponding option for it. You can do that using the special minus (-) operator. For example, here's how you ignore all messages about trailing decimal points (W047):

    /jshint -W047 /

    or

    JSHINT(src, { "-W047": true });

    Keep in mind that this syntax can't be used to ignore errors.

  • Due to popular demand, this version splits indent and white options meaning that indent won't imply white anymore. (#667)

  • Changes node option to not assume that all programs must be running in strict mode. (#721)

  • Adds new globals for the browser option: Element and Uint8ClampedArray. (#707 and #766)

  • Adds new global for the node option: DataView. (#773 and #774)

  • Removes option onecase.

  • Adds new directive: exported. Use /* exported ... for global variables that are defined in the current file but used elsewhere to prevent unnecessary X is defined but never used warnings. As before, you need to declare those variables as global in the other files.

    (#726 and #659)

  • Removes a warning about missing break before default when default is the first switch statement (#490):

    switch (name) { default: // No warning here doSomething(); break; case "JSHint": doSomethingElse(); }

  • Improves support for future reserved keywords. JSHint now properly recognizes future reserved keywords both for ES3 and ES5 environments with their corresponding rules. (#674)

  • Changes behavior for hasOwnProperty (#770):

    var hasOwnProperty = ...; // No warning var obj = { hasOwnProperty: ... }; // Warning obj.hasOwnProperty = ...; // Warning obj['hasOwnProperty'] = ...; // Warning

  • Adds ability to disable option unused per function! (#639)

    // jshint unused:true var a; // Warning

    function foo(b) { // No warning // jshint unused:false return 1; }

    foo();

Bug fixes:

  • Adds scope property to critical errors. (#714)
  • Fixes a regression bug with option predef making all global variables writeable. (#665)
  • Fixes a bug with JSHint not warning about potential typos on return o.a = 1. (#670)
  • Fixes a bug with implied property containing false positive data when option undef is off. (#668)

CLI

  • This version removes support for the JavaScriptCore shell due to its limited API. Note that this doesn't mean that JSHint no longer works in Safari, it simply means that we removed the ability to use jshint via the command line JSC shell.

  • This version also removes support for Windows Script Host. WSH support was initially added due to Node not working well on Windows but, thanks to Microsoft engineers, this is no longer true. So everyone is encouraged to use JSHint with Node.

  • This version relies on ES5 syntax, so if you use JSHint with Rhino, please make sure you have the latest version: 1.7R4.

This version includes several improvements to the Node version of JSHint:

  • Adds a new flag, --verbose, that changes output to display message codes:

    $ jshint --verbose my.js my.js: line 7, col 23, Extra comma. (...) (W070)

  • Makes --config raise an error if it can't find provided file or if the file is invalid JSON. (#691)

Bug fixes:

  • Fixes a bug with .jshintignore globbing not working properly. (#777 and #692)

  • Fixes a bug with JSHint skipping over files with no extensions. (#690)

What's next?

I plan to test this release candidate for about a week before marking it as stable and publishing on NPM. And, at the same time, I will be updating the documentation and the jshint.com website. If you notice any bugs or unexpected backwards-incompatible changes, please file a bug.

RC3 is out: JSHint 1.0.0 RC3.

Here's how you can install this release candidate:

$ npm install https://github.com/jshint/jshint/archive/1.0.0-rc1.tar.gz

For Rhino wrapper, you will need to clone our repo and build jshint-rhino:

$ node make.js build
$ rhino dist/jshint-rhino.js ...

Contributors

Thanks to Bernhard K. Weisshuhn, James Allardice, Mike MacCana, Stephen Fry, Steven Olmsted, Leith Abdulla, Eric Promislow and Vlad Gurdiga for submitting patches!