grunt jshint prints its warnings, the build goes green, and the lint errors accumulate — the worst of both worlds, because the check runs and nobody reads it. Grunt does abort on a task failure and does exit non-zero. The configuration most projects copied from a blog post switches that off.
module.exports = function (grunt) {
grunt.initConfig({
jshint: {
options: {
jshintrc: '.jshintrc',
force: false // the default; copied Gruntfiles set it true
},
all: ['Gruntfile.js', 'assets/js/src/**/*.js']
},
uglify: { /* ... */ }
});
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.registerTask('ci', ['jshint']);
grunt.registerTask('default', ['jshint', 'uglify']);
};
With force off, a failing task ends the run and grunt exits non-zero, which is the only signal a build server reads. force: true demotes the failure to a warning and lets uglify happily minify code that does not lint. The same applies to grunt --force on the command line, which overrides the config entirely and is worth banning from any script Jenkins or Travis invokes. Giving the server its own ci task rather than pointing it at default also stops the build writing minified files nobody will use. The cost of turning this on is one unpleasant day fixing whatever the codebase has accumulated, plus a .jshintrc argument about trailing commas that has to be settled once and then left alone.