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

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/

Related

How to override a TypeScript UMD global type definition?

I have installed three#^0.103.0, which has its own type definitions.
In src/global.d.ts of my project I have:
import * as _THREE from 'three'
declare global {
const THREE: typeof _THREE
}
Then in src/global.ts I have
import * as THREE from 'three'
(window as any).THREE = { ...THREE }
Then in src/my-code.js I am trying to use the THREE as a global variable, f.e.
console.log(new THREE.Vector3(1,2,3)) // ERROR, 'THREE' refers to a UMD global, but the current file is a module. Consider adding an import instead.
It tells me that 'THREE' refers to a UMD global, but the current file is a module. Consider adding an import instead..
When I jump to the definition of THREE, it takes me to node_modules/three/src/Three.d.ts, which is not my src/global.d.ts file.
So, it seems like TypeScript is ignoring my global.d.ts definitions?
My tsconfig.json contains
"allowJs" true,
"checkJs" true,
"include": ["src/**/*"]
and I have global.d.ts is inside of src.
If I add
/// <reference path="./global.d.ts" />
to the top of src/my-code.js file (JavaScript), then it works, and I can jump to the definition of THREE which takes me to my global.d.ts file.
Why does it not work without the reference comment?
For three.js you could declare compiler option allowUmdGlobalAccess in tsconfig.json:
"compilerOptions": {
"allowUmdGlobalAccess": true,
}
This will give typescript access to your project global UMD, where three.js is listed when you install it. Then you could use it at your project same way as for example JQuery.
If this option not available - update your typescript.
Some details
The above should work. There's only one small gotcha:
The two global files have the same name! (i.e. global.ts and global.d.ts)
In this case, TypeScript seems to merge them together (or something), and thus seems to treat global as the same module (as in import './global' being ambiguous).
So, by renaming one module to a different name, it all works.
For example, rename src/global.ts to src/make-global.ts, and leave src/global.d.ts, and it will work.
I was pulling my hair out wondering what was going on until I renamed one of the files.
You should check TypeScript typings resolution strategy in the handbook.
As state there, .ts files have precedence upon .d.ts.
(just bumped into the same problem myself)

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

eslint /* exported functionName */ not working in browser env

I have a few functions that are defined in one js file and used in others. They each have /* exported functionName */ comments and I have my eslint env set to browser/jquery. Based on my reading of the documentation that's all I should need, but it doesn't seem to be working.
What am I doing wrong here?
Here's the .eslintrc (it extends this one, although I get the same behavior without the extends):
{
"extends": "../../.eslintrc",
"env": {
"browser": true,
"jquery": true
}
}
And, here's one of the functions (here's the second and third):
/**
* Returns the next hour as Date
* #return {Date} the next hour
*/
/* exported nextHour */
function nextHour() {
var oneHour = new Date();
oneHour.setHours(oneHour.getHours() + 1);
return oneHour;
}
Finally, this is the output I get from eslint:
/Users/nfriedly/visual-recognition-nodejs/public/js/demo.js
24:10 error 'nextHour' is defined but never used no-unused-vars
37:10 error 'resize' is defined but never used no-unused-vars
/Users/nfriedly/visual-recognition-nodejs/public/js/use.js
26:10 error 'setupUse' is defined but never used no-unused-vars
It works if I replace the /* exported... comment with an // eslint-disable-next-line no-unused-vars but I know that's not the correct solution.
You can check out the complete project from https://github.com/watson-developer-cloud/visual-recognition-nodejs/tree/eslint-exported and then just run npm install; npm test if you want to see it for yourself.
Apparently the Babel-ESLint parser that the airbnb config specifies can override the parsing of config files to break the documented cascading behavior. Setting "parser": null resolves this.
Your config states that you are working in Node environment. Node has an extra scope around every module, so global variables are not really possible in Node (at least not in the same way as in browser). As such, when no-unused-vars rule sees any environment with globalReturn flag on (Node, CommonJS, shared-node-browser) or modules on, it ignores /* exported */ comments. You need to remove Node environment and enable browser environment if you want to use global variables and exported comments.

jshint error: Redefinition of '$'

I have a Node.js web application where I use Backbone.js and jQuery. My main js file is app.js where I include all the necessary scripts, including jQuery. So, this is the beginning of my app.js code:
'use strict';
var _ = require('lodash');
var $ = require('jquery');
var B = require('backbone');
B.$ = $;
Now if I run grunt on my project, it raises errors at the line where jQuery is loaded to $. It shows me this:
Linting public/js/app.js ...ERROR
[L4:C5] W079: Redefinition of '$'.
var $ = require('jquery');
I can still get everything running with grunt --force, but I would like to eliminate this error anyway. Can somebody explain why it raises the error and how to fix it?
My .jshintrc file:
{
"laxcomma": true
,"laxbreak": true
,"curly": true
,"eqeqeq": true
,"immed": true
,"latedef": true
,"newcap": true
,"noarg": true
,"sub": true
,"undef": true
,"unused": false
,"asi": true
,"boss": true
,"eqnull": true
,"node": true
,"browser": true
,"jquery": true
,"predef":
[
"suite"
,"test"
,"setup"
,"teardown"
,"suiteSetup"
,"suiteTeardown"
,"requestAnimationFrame"
]
}
In jshint docs: http://www.jshint.com/docs/options/
jquery = true
This option defines globals exposed by the jQuery JavaScript library.
You are telling jshint that jquery exists, thus he assumes that $ is defined. Remove the "jquery" : true" and your issue should go away.
Add this at the top of the file to make that error go away:
/* jshint -W079 */
What's happening here is that JQuery defines the $ variable, so JSHint views this as a piece of "potentially dangerous code"
A better solution would be to require jquery directly which should give you access to the $ variable globally.
Random guess: do you include jquery somewhere else? For example in some html file as a script. Or some other script might be defining global jquery variable.
Make sure that in your .jshintrc you don't have '$' set as predefined.
// Predefined Globals
"predef" : ["$"]
If it is, remove.

Grunt lint error with $

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
}
}
}

Categories

Resources