I've got a Grunt setup which uses Karma+Jasmine and JSHint. Whenever I run JSHint on my spec file, I get a series of "undefined" errors, most of which are for Jasmine's built-in functions. For example:
Running "jshint:test" (jshint) task
js/main.spec.js
3 |describe("loadMatrix()", function() {
^ 'describe' is not defined.
4 | it("should not assign a value if no arg is passed.", function() {
^ 'it' is not defined.
(I also get some undefined errors for the variables and functions from the JS file that my spec is meant to test against, but I'm not sure why that is and it may be a separate issue.)
My Karma config file has frameworks: [ "jasmine" ] in it, I don't have any globals set for JSHint, and I don't have a .jshintrc file since I'm configuring it in Grunt. I did try adding Jasmine's functions as JSHint globals in my Gruntfile at one point, but setting them as either true or false didn't make a difference—the errors still persisted when JSHint ran.
What am I missing? I can't seem to do anything to get JSHint to skip definition checking for Jasmine's functions in my spec file.
You can just add "jasmine": true to your .jshintrc file.
MINOR CORRECTION - there should be "" around predef in the .jshintrc file.
Fixed by adding this to the jshint options in my Gruntfile.coffee:
predef: [
"jasmine"
"describe"
"xdescribe"
"before"
"beforeEach"
"after"
"afterEach"
"it"
"xit"
"it"
"inject"
"expect"
"spyOn"
]
.jshintrc:
"predef": [
"jasmine",
"describe",
"xdescribe",
"before",
"beforeEach",
"after",
"afterEach",
"it",
"xit",
"it",
"inject",
"expect",
"spyOn",
]
I fixed this in Gruntfile.js adding jasmine: true to the options of the jshint task:
jshint:
{
options:
{
...
node: true,
jasmine: true,
...
},
...
},
Like the OP, I'm not using a .jshintrc file either.
I believe the other answers are correct, but I have never seen such exception before, however I see it now. Then I noticed that my tests are not in IIFE.
So I moved them in IIFE like this and I no longer get such JSHINT warnings.
(function () {
describe('foo', () => {
it('bar', () => {
expect(1+1).toEqual(2);
});
});
})();
Related
I include the statement:
"use strict";
at the beginning of most of my Javascript files.
JSLint has never before warned about this. But now it is, saying:
Use the function form of "use strict".
Does anyone know what the "function form" would be?
Include 'use strict'; as the first statement in a wrapping function, so it only affects that function. This prevents problems when concatenating scripts that aren't strict.
See Douglas Crockford's latest blog post Strict Mode Is Coming To Town.
Example from that post:
(function () {
'use strict';
// this function is strict...
}());
(function () {
// but this function is sloppy...
}());
Update:
In case you don't want to wrap in immediate function (e.g. it is a node module), then you can disable the warning.
For JSLint (per Zhami):
/*jslint node: true */
For JSHint:
/*jshint strict:false */
or (per Laith Shadeed)
/* jshint -W097 */
To disable any arbitrary warning from JSHint, check the map in JSHint source code (details in docs).
Update 2: JSHint supports node:boolean option. See .jshintrc at github.
/* jshint node: true */
If you're writing modules for NodeJS, they are already encapsulated. Tell JSLint that you've got node by including at the top of your file:
/*jslint node: true */
I'd suggest to use jshint instead.
It allows to suppress this warning via /*jshint globalstrict: true*/.
If you are writing a library, I would only suggest using global strict if your code is encapsulated into modules as is the case with nodejs.
Otherwise you'd force everyone who is using your library into strict mode.
I started creating a Node.js/browserify application following the Cross Platform JavaScript blog post. And I ran into this issue, because my brand new Gruntfile didn't pass jshint.
Luckily I found an answer in the Leanpub book on Grunt:
If we try it now, we will scan our Gruntfile… and get some errors:
$ grunt jshint
Running "jshint:all" (jshint) task
Linting Gruntfile.js...ERROR
[L1:C1] W097: Use the function form of "use strict".
'use strict';
Linting Gruntfile.js...ERROR
[L3:C1] W117: 'module' is not defined.
module.exports = function (grunt) {
Warning: Task "jshint:all" failed. Use --force to continue.
Both errors are because the Gruntfile is a Node program, and by default JSHint does not recognise or allow the use of module and the string version of use strict. We can set a JSHint rule that will accept our Node programs. Let’s edit our jshint task configuration and add an options key:
jshint: {
options: {
node: true
},
}
Adding node: true to the jshint options, to put jshint into "Node mode", removed both errors for me.
Add a file .jslintrc (or .jshintrc in the case of jshint) at the root of your project with the following content:
{
"node": true
}
There's nothing innately wrong with the string form.
Rather than avoid the "global" strict form for worry of concatenating non-strict javascript, it's probably better to just fix the damn non-strict javascript to be strict.
process.on('warning', function(e) {
'use strict';
console.warn(e.stack);
});
process.on('uncaughtException', function(e) {
'use strict';
console.warn(e.stack);
});
add this lines to at the starting point of your file
I think everyone missed the "suddenly" part of this question. Most likely, your .jshintrc has a syntax error, so it's not including the 'browser' line. Run it through a json validator to see where the error is.
This is how simple it is: If you want to be strict with all your code, add "use strict"; at the start of your JavaScript.
But if you only want to be strict with some of your code, use the function form. Anyhow, I would recomend you to use it at the beginning of your JavaScript because this will help you be a better coder.
I have the following error for my files in tests:
Expected an assignment or function call and instead saw an expression.
It is generated from Chai libraries asserts. How can I turn it off in my .jshintrc file? I run a Gulp task based on it.
Here's how you can silence it inside of a .jshintrc file.
{
...
"expr": true
...
}
Source: http://jshint.com/docs/options/#expr
You can add the following on top of the line that's generating the error :
/*jshint -W030 */
Reference : http://jslinterrors.com/expected-an-assignment-or-function-call
I uses RequireJS AMD in my project. When i run jshint on my project, it throws error like
In AMD Scripts
'define' is not defined.
In Mocha test cases
'describe' is not defined.
'it' is not defined.
How to remove this warning in jshint?
Just to expand a bit, here's a .jshintrc setup for Mocha:
{
....
"globals" : {
/* MOCHA */
"describe" : false,
"it" : false,
"before" : false,
"beforeEach" : false,
"after" : false,
"afterEach" : false
}
}
From the JSHint Docs - the false (the default) means the variable is read-only.
If you are defining globals only for a specific file, you can do this:
/*global describe, it, before, beforeEach, after, afterEach */
jshint: {
options: {
mocha: true,
}
}
is what you want
To avoid the not defined warning in jshint for the javascript add comments like:
/*global describe:true*/
Options
Add this in your .jshintrc
"predef" : ["define"] // Custom globals for requirejs
late to the party, but use this option in your jshintrc:
"dojo": true
and thou shall rest peacefully without red warnings...
If you are working on node js. Add these two lines in the beginning of your file
/*jslint node: true */
"use strict";
Read the docs and search for /*global
If you're trying to run JSHint in WebStorm with Mocha, as I am, go into:
WebStorm > Preferences > Languages & Frameworks > JavaScript > Code Quality Tools > JSHint
Scroll down to "Environments" and make sure you have selected the checkbox to enable "Mocha" which will set up the definitions for JSHint for Mocha for you.
I include the statement:
"use strict";
at the beginning of most of my Javascript files.
JSLint has never before warned about this. But now it is, saying:
Use the function form of "use strict".
Does anyone know what the "function form" would be?
Include 'use strict'; as the first statement in a wrapping function, so it only affects that function. This prevents problems when concatenating scripts that aren't strict.
See Douglas Crockford's latest blog post Strict Mode Is Coming To Town.
Example from that post:
(function () {
'use strict';
// this function is strict...
}());
(function () {
// but this function is sloppy...
}());
Update:
In case you don't want to wrap in immediate function (e.g. it is a node module), then you can disable the warning.
For JSLint (per Zhami):
/*jslint node: true */
For JSHint:
/*jshint strict:false */
or (per Laith Shadeed)
/* jshint -W097 */
To disable any arbitrary warning from JSHint, check the map in JSHint source code (details in docs).
Update 2: JSHint supports node:boolean option. See .jshintrc at github.
/* jshint node: true */
If you're writing modules for NodeJS, they are already encapsulated. Tell JSLint that you've got node by including at the top of your file:
/*jslint node: true */
I'd suggest to use jshint instead.
It allows to suppress this warning via /*jshint globalstrict: true*/.
If you are writing a library, I would only suggest using global strict if your code is encapsulated into modules as is the case with nodejs.
Otherwise you'd force everyone who is using your library into strict mode.
I started creating a Node.js/browserify application following the Cross Platform JavaScript blog post. And I ran into this issue, because my brand new Gruntfile didn't pass jshint.
Luckily I found an answer in the Leanpub book on Grunt:
If we try it now, we will scan our Gruntfile… and get some errors:
$ grunt jshint
Running "jshint:all" (jshint) task
Linting Gruntfile.js...ERROR
[L1:C1] W097: Use the function form of "use strict".
'use strict';
Linting Gruntfile.js...ERROR
[L3:C1] W117: 'module' is not defined.
module.exports = function (grunt) {
Warning: Task "jshint:all" failed. Use --force to continue.
Both errors are because the Gruntfile is a Node program, and by default JSHint does not recognise or allow the use of module and the string version of use strict. We can set a JSHint rule that will accept our Node programs. Let’s edit our jshint task configuration and add an options key:
jshint: {
options: {
node: true
},
}
Adding node: true to the jshint options, to put jshint into "Node mode", removed both errors for me.
Add a file .jslintrc (or .jshintrc in the case of jshint) at the root of your project with the following content:
{
"node": true
}
There's nothing innately wrong with the string form.
Rather than avoid the "global" strict form for worry of concatenating non-strict javascript, it's probably better to just fix the damn non-strict javascript to be strict.
process.on('warning', function(e) {
'use strict';
console.warn(e.stack);
});
process.on('uncaughtException', function(e) {
'use strict';
console.warn(e.stack);
});
add this lines to at the starting point of your file
I think everyone missed the "suddenly" part of this question. Most likely, your .jshintrc has a syntax error, so it's not including the 'browser' line. Run it through a json validator to see where the error is.
This is how simple it is: If you want to be strict with all your code, add "use strict"; at the start of your JavaScript.
But if you only want to be strict with some of your code, use the function form. Anyhow, I would recomend you to use it at the beginning of your JavaScript because this will help you be a better coder.
I'm currently setting up a automated build script (with gruntjs) for a require.js driven project . Therefor I would like to run jslint/jshint on all required files before concatenating and minifying it with r.js. Since the js folder contains a lot of development files I don't want to lint, I can't just pass js/**/*.js to JSLint. My first thought was to run r.js with optimizer: 'none', lint the concatenated file and then minify it, but this is not an options for two reasons. First it will include vendor libs I don't want to lint and second finding the line with the error, find it's class, find the appropriate js-file in the dev folder, fix it there, run r.js again and finally lint it again, is way to much hassle for our workflow. So I'm looking for a possibility to hook up the linting into the r.js optimizer process or at least get a list of the requirejs dependency tree in some way, that I can parse and pass it to lint. Or any solution practicable for an automated process, you'll come up with.
Lint first, compile later. Just be specific about the files you want to lint and use the ! prefix to ignore specific files:
grunt.initConfig({
lint: {
// Specify which files to lint and which to ignore
all: ['js/src/*.js', '!js/src/notthisfile.js']
},
requirejs: {
compile: {
options: {
baseUrl: 'js/src',
name: 'project',
out: 'js/scripts.js'
}
}
}
});
// Load the grunt-contrib-requirejs module.
// Do `npm install grunt-contrib-requirejs` first
grunt.loadNpmTasks('grunt-contrib-requirejs');
// Our default task (just running grunt) will
// lint first then compile
grunt.registerTask('default', ['lint', 'requirejs']);
I prefer not overriding r.js's methods, or you might create an unwanted dependency on a specific version (you'll need to update your code should r.js change)
This is the code I use for the same purpose, making use of require's onBuildRead function and the fact that objects in javascript are passed by reference. I make sure I run the require build first, then lint the js file sources.
The downside is that you'll lint after build complete. For my setup that is not a problem.
module.exports = function(grunt) {
var jsHintOptions = {
options: {
curly: true,
eqeqeq: true,
eqnull: true,
browser: true,
globals: {
jQuery: true
}
},
all: [] // <--- note this is empty! We'll fill it up as we read require dependencies
};
var requirejsOptions = {
compile: {
options: {
paths: {
"jquery": "empty:"
},
baseUrl: "./",
name: "src/mypackage/main",
mainConfigFile: "src/mypackage/main.js",
out: 'build/mypackage/main.js',
onBuildRead: function (moduleName, path, contents) {
jsHintOptions.all.push(path); // <-- here we populate the jshint path array
return contents;
}
}
}
};
grunt.initConfig({
pkg: grunt.file.readJSON('packages/mypackage.package.json'),
requirejs: requirejsOptions,
jshint: jsHintOptions
});
// load plugin that enabled requirejs
grunt.loadNpmTasks('grunt-contrib-requirejs');
// load code quality tool
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.registerTask('default', ['requirejs', 'jshint']); // <-- make sure your run jshint AFTER require
};
This answer sort of bypasses Grunt, but it should work for what you want to do. The way I would do it is look at r.js and try to override a function that receives the path to the various modules being loaded, intercept the module name, and lint the files while r.js is loading and compiling the modules. I've done it like so:
var requirejs = require('requirejs');
var options = {/*r.js options as JSON*/};
var oldNewContext = requirejs.s.newContext;
requirejs.s.newContext = function(){
var context = oldNewContext.apply(this, arguments);
var oldLoad = context.Module.prototype.load;
context.Module.prototype.load = function(){
var module = oldLoad.apply(this, arguments);
if(/\.js$/.test(this.map.url) && !/^empty:/.test(this.map.url))
console.log(this.map.url);
return module;
}
return context;
}
requirejs.optimize(options)
Then when you run requirejs.optimize on your modules, you should get all the non-empty JavaScript urls logged to the console. Instead of logging them to the console, you could use the urls to lint the files.
Instead of using the lint task, install, load, and set up grunt-contrib-jshint. It has an ignores option to ignore specific files or file path patterns.
Here's my task:
jshint: {
options: {
// options here to override JSHint defaults
boss : true, // Suppress warnings about assignments where comparisons are expected
browser : true, // Define globals exposed by modern browsers (`document`, `navigator`)
curly : false, // Require curly braces around blocks
devel : false, // Define `console`, `alert`, etc. (poor-man's debugging)
eqeqeq : false, // Prohibit the use of `==` and `!=` in favor of `===` and `!==`
"-W041" : false, // Prohibit use of `== ''` comparisons
eqnull : true, // Suppress warnings about `== null` comparisons
immed : true, // Prohibit the use of immediate function invocations w/o wrapping in parentheses
latedef : true, // Prohibit the use of a var before it's defined
laxbreak: true, // Suppress warnings about possibly unsafe line breaks
newcap : true, // Require you to capitalize names of constructor functions
noarg : true, // Prohibit the use of `arguments.caller` and `arguments.callee`
shadow : true, // Suppress warnings about var shadowing (declaring a var that's declared somewhere in outer scope)
sub : true, // Suppress warnings about using `[]` notation, e.g. `person['name']` vs. `person.name`
trailing: true, // Trailing whitespace = error
undef : false, // Prohibit the use of explicitly undeclared variables
unused : false, // Warn when you define and never use your variables
white : false, // Check JS against Douglas Crawford's coding style
jquery : true, // Define globals exposed by jQuery
// Define global functions/libraries/etc.
globals : {
amplify : true
},
ignores: [
'src/app/templates/template.js',
'src/scripts/plugins/text.min.js'
]
},
gruntfile: {
src: 'Gruntfile.js'
},
app: {
src: 'src/app/**/*.js'
},
scripts: {
src: 'src/scripts/**/*.js'
}
}