Adding a linter to your project is a wise decision. A linter is a tool that analyses your code and looks for syntax errors, bad practises and badly formatted code.
A popular JavaScript linter is JSHint, which you can try online. JSHint provides a sensible default ruleset, but you can customise it to suit your needs.
As with most front-end common tasks, there is a plugin for JSHint, grunt-contrib-jshint
. You need to install it via npm
and then load the task in the Gruntfile.js
:
$ npm install grunt-contrib-jshint
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.initConfig({
jshint: {} // config happens here
});
};
Now on to scanning the code!
Configuration is very similar for every Grunt task / plugin. You usually need to supply some files that will be passed as input, plus some configuration options.
In the jshint
task that you imported, the files supplied as input will be the files the linter will scan. There are different ways to supply these files, and we will see some of them through this Grunt chapter.
The most simple way to supply input files, is by setting an array of filenames in a files
key:
grunt.initConfig({
jshint: {
files: ['Gruntfile.js']
}
});
If you run the jshint
task now, you will see that the linter will scan one file:
$ grunt jshint
If you want to see more output in the tasks you run, you can add the --verbose
flag:
$ grunt jshint --verbose
If you try that, you will see which files exactly were scanned (in this case Gruntfile.js
).
On the inside, Grunt makes use of minimatch to match filenames. This is a nice library that allow the use of globbing to refer to multiple files, and it will make your life easier. You could have, for instance:
files: ['Gruntfile.js', 'app/*.js']
And that would make JSHint to scan Gruntfile.js
and all the files with .js
extension that are immediately under the app
directory.
Note that this will match app/main.js
, but not app/models/user.js
, since user.js
is not directly under app
, but in a subdirectory. If you want to use recursive matching, make use of globstar (**
):
files: ['Gruntfile.js', 'app/**/*.js']
Besides files, you usually supply some configuration options to the task. These depend on the task itself, so you will have to read the plugin's documentation to see what is available to you.
The JSHint plugin for Grunt allows us to configure some of the rules that will be applied[^rules]. For instance, if you want to enforce the use of Strict mode in your code, you need to set the strict
option to true
:
grunt.initConfig({
jshint: {
files: ['Gruntfile.js'],
options: {
strict: true
}
}
});
A common practice in projects which use JSHint is to have the rules defined in a .jshintrc
file so the same configuration can be shared across text editors, continuous integration systems, etc.
If you want to use this feature, just create a .jshintrc
JSON file with your rules inside and then set the option jshintrc
to true
:
grunt.initConfig({
jshint: {
files: ['Gruntfile.js'],
options: {
jshintrc: true
}
}
});
Here's a sample .jshintrc
you can try:
{
"strict": true
}
[^rules]: You can see all the rules available at JSHint's documentation.
[^browser-rule]: This rule will allow the use of global variables available in browsers, like document
or FileReader
.