Grunt lint error with $ - javascript

I'm trying to use lint with Grunt. I'm able to run Grunt from the command line but it is giving me a lot of errors. Mostly "'$' is not defined". Even alert is throwing an error, "'alert' is not defined".
How can I get around those?

You need to tell JSHint (which is the linter that Grunt uses by default) about the global variables available to the files being linted. I'm assuming that you're including jQuery on your pages, hence the $ identifier (could be various other libraries of course).
You can either specify global variables in each file, or in the Grunt script. To specify them in a file, you can use a global directive. Place this at the top of the file, or at the top of the function in which you use the global:
/*global $:false */
Note that the false means you'll get errors if you override $. If you need the ability to do that, change it to true.
If you'd prefer to specify globals in the Grunt script, you can add a globals property to any of the tasks in your jshint section. For example:
grunt.initConfig({
jshint: {
someTask: {
globals: {
$: false
}
}
}
});
As for the alert message you're getting, you need to tell JSHint that you're allowing the use of development functions, such as alert and console.log. To do that, you can use a jshint directive in the files (just like the global directive):
/*jshint devel:true */
Or you can add an options property to the task in the Grunt script:
someTask: {
globals: {
$: false
},
options: {
devel: true
}
}
See the JSHint docs for all of the options available to you.

globals must be inside options
someTask: {
options: {
devel: true,
globals: {
$: false
}
}
}

Related

how to fix error for "Expected an assignment or function call and instead saw an expression" [duplicate]

In my Chai tests I often find myself wanting to use their assertions that are something like .to.be.empty, .to.be.true e.t.c., because I find them to be cleaner to read than .to.be.length(1) or .to.be.equal(true). However, this breaks my linter (I'm using default Airbnb linting).
I could use the // disable-eslint-line syntax, but then I'd have to add it to every single line that reads like that and that seems tedious.
I've also read about the DirtyChai library, but that would require me to go back through my entire testing library adding brackets to them all which seems like something I shouldn't have to do simply to get my linter to pass something it should probably be OK with in the first place.
Does anyone know a nicer way to handle this than the ways I've outlined above?
You can disable the rule for the entire file using eslint-disable at the top of the file in question:
/* eslint-disable no-unused-expressions */
expect(someTrueValue).to.be.true;
However, adding this at the top of every test file can be tedious. To disable this rule for all relevant files, you can:
Put a new .eslintc configuration file in the same directory as your test files, configured to disable that rule. This allows you to use the default configuration for all other rules while ignoring that rule specifically only on files in that folder. ESLint calls this Configuration Cascading.
{
"rules": {
"no-unused-expressions": "off"
}
}
Use the overrides key in your main .eslintrc file to disable rules for groups of files with glob pattern matching:
{
"overrides": [
{
"files": ["*.test.js", "*.spec.js"],
"rules": {
"no-unused-expressions": "off"
}
}
]
}
This also allows you to disable other rules which become troublesome in testing, such as no-underscore-dangle when using rewire.
Just found another option using Relative Glob Patterns:
In your .eslintrc file:
"overrides": [
{
"files": "*.test.js",
"rules": {
"no-unused-expressions": "off"
}
}
]
I've made a small plugin called eslint-plugin-chai-friendly that overrides the default no-unused-expressions rule and makes it friendly towards chai. The modified rule ignores the expect and should statements while keeping default behavior for everything else.
Combining jonalvarezz's answer with Ihor Diachenko's answer gave me exactly what I wanted:
npm install --save-dev eslint-plugin-chai-friendly
// .eslintrc.js
module.exports = {
// ...
plugins: ['chai-friendly'],
overrides: [{
files: '*.test.js',
rules: {
'no-unused-expressions': 'off',
'chai-friendly/no-unused-expressions': 'error',
},
}],
// ...
}
This way, the no-unused-expression rule will only be overridden in *.test.js files
AND
a no-unused-expression rule will still be in place to catch any unused expressions in the test files that are unrelated to chai.
In case anyone is stumbling upon this today, I had the same issue and found this solution on eslint documentation. In your eslint configuration file, you can specify one or several environments, which will predefine global variables for this environment. For us, it'd be mocha, and you'd configure like this in your .eslintrc.json:
{
"env": {
"mocha": true
},
...
...
...
}
As a result, it will remove all false positive about mocha describe, it, beforeEach, etc. without needing to completely disable eslint or completely disable any specific rule.
Tested with ESLint v.4.11 and mocha 5.0
I had this issue with tslint and solved it by simply moving the rule for unused expressions down one level. My ./tslint.json has all the other rules I care about, then I made ./src/tslint.json that just looks like
{
"rules": {
"no-unused-expression": true
},
"extends": "../tslint.json"
}
tslint automatically checks for a config file in every level as it descends the tree (with --project or using the VSCode extension) so this means that my tests (under ./test/) have all the other rules applied, but no-unused-expression only applies to files under ./src/.

xo lint error: `document` is not defined

I've been a long time user of Standard, and now that I'm working on a new project, I've been asked to start writing semicolons.
I'm trying to use both xo, Babel and React, but I keep getting an error when I try to lint my code:
document is not defined. no-undef
I've tried adding an env option to the xo field in my package.json file, but no success.
My xo config:
"xo": {
"esnext": true,
"extends": "xo-react",
"space": true,
"rules": {
"react/jsx-space-before-closing": 0
}
}
It is cumbersome to specify linting options such as /** global document **/ and edit a configuration file every time you use a global.
This error can be suppressed by using --env=browser option:
xo --env=browser [<file|glob> ...]
Note: Same problem comes with Node.js, where the linter will complain that require and friends are not defined. The switch has to change to --env=node in that case.
However, XO defaults the env to node, therefore this will not be a problem in most cases. You will need multiple environments if your project contains both client and server files. in that case, --env switch can be set multiple times:
xo --env=browser --env=node [<file|glob> ...]
You have to define globals in ESLint. There are two ways to accomplish this, firstly as a comment in your code:
/* global document */
Or you can configure in configuration file like so:
{
"globals": {
"var1": true,
"var2": false
}
}
See the ESLint docs for more

browserify - exclude code blocks?

I'm building an app with shared React components in the browser and server-side Node.
Right now, I'm using Marty.js to do this:
function getUser() {
if (Marty.isBrowser) {
/* Get user using some client method */
} else {
/* otherwise, use some secret server code */
}
}
I'm bundling those functions up via Browserify, so they can run on the client as well as the server.
What I'd like to do is remove the else block from the bundle entirely, so I'm not leaking sensitive server-side code.
Is there a way to exclude blocks of code from the bundle?
I would create separate modules, one for the browser and one for the server. Then in your package.json, you tell browserify to use the browser module:
"browser": {
"./path/to/node-module.js": "./path/to/browser-module.js"
}
Now, whereever you call require('path/to/node-module'), browserify will load the other module instead.
More information from the docs:
browser field
There is a special "browser" field you can set in your package.json on a per-module basis to override file resolution for browser-specific versions of files.
For example, if you want to have a browser-specific module entry point for your "main" field you can just set the "browser" field to a string:
"browser": "./browser.js"
or you can have overrides on a per-file basis:
"browser": {
"fs": "level-fs",
"./lib/ops.js": "./browser/opts.js"
}
Note that the browser field only applies to files in the local module, and like transforms, it doesn't apply into node_modules directories.
While I'm not sure if it possible with Browserify, you can do it with Webpack using its DefinePlugin
From the docs (little modified):
Example:
new webpack.DefinePlugin({
DEBUG: false,
PRODUCTION: true,
...
})
...
Example:
if(DEBUG)
console.log('Debug info')
if(PRODUCTION)
console.log('Production log')
After passing through webpack with no minification results in:
if(false)
console.log('Debug info')
if(true)
console.log('Production log')
and then after a minification pass results in:
console.log('Production log')
You can use an environment variable, envify and uglify to do this.
if ('browser' === process.env.ENVIRONMENT) {
...
}
else {
...
}
Set process.env.ENVIRONMENT = 'browser' when doing your browser build, use the envify transform to substitute references to process.env with their current values and uglify will then perform dead code elimination to remove the branches which will never be hit.
Be more explicit about your intent, and put your code in their own files:
function getUser(options, callback) {
var fn;
if (Marty.isBrowser) {
fn = require("./lib/users/get.browser");
} else {
fn = require("./lib/users/get.server");
}
fn(options, callback);
}
and then as a browserify option you can say "replace require("./lib/users/get.server") with this variable instead, when you see it: ..." so that you don't build in that server file when you build for the browser.
However, if getUser can do different things based on where it's running, it feels far more likely that you're doing something wrong here: maybe that getUser should be a REST call to your server from the browser instead, but without more information, that's always hard to determine.
What about putting the code in a module for example UserServer and then exclude that module when you are compiling for the client? Your code becomes:
function getUser() {
if (Marty.isBrowser) {
/* Get user using some client method */
} else {
require('UserServer').getUser();
}
}
Browserify provides the following option to exclude files from the bundle:
--exclude, -u Omit a file from the output bundle. Files can be globs.

How to tell JSLint / JSHint what global variables are already defined

In my project we have some global variables that work as containers:
MyProject.MyFreature.someFunction = function() { ... }
So then I use that script across the site and JSLint / JSHint complains about that:
'MyProject' is not defined
I know that I can go to every JavaScript file and add the comment /*global MyProject*/ on top of it. But I'm looking a way to define that comment in some sort of config file so I don't have to go file by file adding this comment.
Some kind on option in the config/jshint.yml would be nice.
For JSHint you can create .jshintrc to your project directory with
{
"globals": { "MyProject": true }
}
This is only for globals
/* global MyProject */
In your case you need
/* exported MyProject */
JSLint has a textarea below the options that says predefine global variables here in it. Just add the variable names in there before running the check.
JSHint doesn't allow you to add global variables, but you can uncheck the When variable is undefined option to suppress that warning.
The JSHint library also has parameters for globals, if you run it as a library . . . details in here: http://jshint.com/docs/

How to disable the warning 'define' is not defined using JSHint and RequireJS

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.

Categories

Resources