Insights and discoveries
from deep in the weeds
Outsharked

Thursday, August 18, 2011

sharpLinter: run JSLint and JSHint in Visual Studio and from the command line

sharpLinter Resources

There are a few options out there for automating "linting" your Javascript within the VS IDE. The most prominent one JSLint for Visual Studio 2010, a VS extension. Then there are a bunch of different relatively hacky ways that people have come up with to do this. None of them really did it for me, so I rolled something new. The result is sharpLinter, a C# command line application and class library for running JSLINT (or JSHINT) against your Javascript files.

This work is based on Luke Page's early crack at linting in Visual Studio from late 2010. Luke went on to create the extension I mentioned before, offering some UI integration.

OK, so there's already a VS extension, why sharpLinter?

This plug-in is cool, but I found it had some annoying shortcomings. It kept forgetting what files I'd told it to exclude from processing, so I'd end up having thousands of errors from every 3rd party script included in my project before long. These exclusions had to be specified in the GUI, one at a time or with multiple-click-select. Argh! There seems to be no way to just tell it to include or exclude entire paths or patterns, which is what I really wanted. Configuration was fairly limited, and the feature to skip blocks within files didn't seem to be recognized either. And finally, you were stuck with whatever JSLINT or JSHINT it had compiled into it!

Well, all that could probably be addressed by the author or some other industrious soul. But ultimately, it was designed to be an extension for Visual Studio. While I wanted that, I also something I could easily integrate with automated processes, or as a quick and dirty way to run against any file in any situation. I wanted a library and command line tool.

It's not a real Visual Studio extension. That means you need to configure it as an "external tool." But it produces output formatted for VS, so you can still just click on a line in the output window, and it will jump directly to that file and line. Frankly, all the config features in the the VS extension seem like more of a hindrance than a benefit to me. The lint options are limited to what was part of the script when the extension was coded, and the settings all seemed to work erratically. All I really wanted was to set up a configuration for my project, then "run, click, and go to the error." That's all here.
Example output within Visual Studio. Enlarge.

sharpLinter is all these things.

But wait, there's more!

If you act now you also get instant minification!
sharpLinter can be configured to automatically minify your scripts after they pass validation using Yahoo YUI compressor, or Dean Edwards' JSPacker. Your choice, or let sharpLinter decide how to minimize, and it will just use the one that produces the smallest script. There's even an option to preserve the first comment block of your script in the output, so you can keep your credit & license information intact, if you choose.

To keep you safe from version confusion, if you have this option enabled and a script fails, any existing minimized script matching the output pattern for just the file that failed will be deleted.

How's it work?

Complete usage instructions and command-line options are in the readme on github. Basic command-line usage is as follows:
sharplinter [-[r]f path/*.js] [o options] [-v]
        [-c sharplinter.conf] [-j jslint.js] [-y]
        [-p[h] yui|packer|best mask] [-k]
        [-i ignore-start ignore-end] [-if text] [-of "format"]
The options let you:
  • [-[r]f] specify a file, folder, or grep mask to parse. If [r] is included, will recurse subfolders too.
  • [-c] specify a file with global configuration options
  • [-j] specify the actual code to run the checks (hopefully, one of JSLINT or JSHINT). If you leave this out, sharpLinter will look for a file called jslint.js in its executable directory. If that's not found, it will use the code embedded in itself (JSHINT as of 8/15/11, at the time of this writing).
  • [-o] specify options to pass directly to the linter
  • [-p[h]] tell it to minimize the output, using a particular (or best) strategy, and define a template for the filename of the minimized version. If called with -h, then the first comment block will be preserved.
  • [-i] specify text to use as markers for ignore blocks, or [-if] to skip an entire file
  • [-y] tell it to run Yahoo YUI against the file as well as the linter, and report its errors too
  • [-v] be verbose -- will report lots of information about what its doing other than errors. Normally, only errors are reported, or a single success line if there were no errors.
  • [-of] define an output format string for the error reports using parameters for error, source, line, and character. So maybe you want to use this to feed something other than visual studio? You can format the output any way you want.
  • [-k] wait for a keystroke when finished
All the core functionality is wrapped into a class library, so it should be easy to integrate this into another project (e.g. not from the command line). One caveat - this must be compiled with x86 as the target platform. It will not work if "any" (e.g. x64 or x86) is specified, because the Neosis V8 engine wrapper is a 32 bit only application.

Enjoy, let me know if you find problems or have questions, or just fork it!

3 comments:

  1. I had to remove these 3 lines:

    sloppy: false,
    type: true,
    windows: true,

    from the /*jslint...jslint*/ section of jslint.global.conf to get it to work.

    Otherwise, awesome!

    ReplyDelete
    Replies
    1. Are you using with jslint (vs. jshint)? SharpLinter does validate that you pass options it knows about, those are only valid for jshint.

      I should probably add an option to not do this, since its list of valid options could get out of date easily.

      Delete
  2. Has anyone figured out a way to create an xml output file from sharplinter, so that Jenkins can read it into the violations plugin?

    ReplyDelete