1

Here's the problem: I'm using JSHint in Grunt. I have a couple JS files and they'll be merged into one file in the end. But before merging, I would like to run JSHint. However, JSHint complaints some undefined variables. Here's an example: 1. JavaScript/file_one.js defines a variable: var Foo = (function (){}()); 2. JavaScript/file_two.js uses that module. new Foo().

jshint: {
            files: ['Gruntfile.js',
                    'javascript/**/*.js',

                   ],
             options: {
             // some options.
         }
}

JSHint complaints that Foo isn't defined in file_two.js.

Here are my goals (if possible): 1. I want to have codes in separate files. So it's possible that some variable is defined in a different file. 2. I want JSHint to check the origin JS files. I don't want to merge all JS files to one and have JSHint to check the merged one. 3. JSHint can check across all files in <%= jshint.files %> (javascript/**/*.js for example) and look for definition.

I know one work around that to put Foo as a global in options, as in this post How to tell JSLint / JSHint what global variables are already defined. But I don't want to put the variable I defined there, since every such variable is in my source files.

So my question is whether there's a way to achieve my goal 3 to tell JSHint to look for the definition in other files.

Community
  • 1
  • 1
Mao
  • 107
  • 7
  • The only "solution" I know of is to specify this at the top of file_two.js: `/*global Foo*/`, sorry... That said, you could write a custom Grunt task to do something like this, wouldn't be terribly difficult, but not terribly simple, either. – Jordan Kasper Jan 04 '15 at 22:20
  • After thinking about it more, I don't think "detecting" the global variables in your other files and allowing JSHint to bypass them is even a good idea. Think about it, if you have some sort of auto-detection, how can it know the difference between a global module versus a global var leak? I think you either have to define all globals in the `.jshintrc` file, or disable the undefined var detection. – Jordan Kasper Jan 05 '15 at 13:36
  • You may make a good point. But if I follow the coding convention not to use global vars, add every global module in .jshintrc seems unnecessary to me if jshint knows it's defined in other files. I think my goal is to let jshint figure out where the module is automatically. But it seems impossible. – Mao Jan 07 '15 at 06:10

3 Answers3

2

Use the following, which has the benefit of not using JSHint configuration at all.

In the first file (the file which gives the variable its initial value):

var username = "guest";   // it becomes: window.username

In the other (second, third) file(s):

var username = window.username;

Various notes:

By declaring with var, it becomes a property of the window (global) object (the window.username). Use var, so you can declare it multiple times (let can't do that).

The same can be done with functions using function expressions (not function declarations).

If the variable is an object (for example, function) or you do not need to change its value, you can also use let in the second file. Another option is to not declare it at all in the second file. In this case, use window every time you use it:

console.log(window.username);

Using this technique, it has the additional advantage that you can distinguish your "super global" variables (the ones that you declare with var and are attached to the global object - window) from the "just global" ones (that you declare with let, as you should, and are attached to the global context but not the global object).

Dim Vai
  • 726
  • 8
  • 14
0

Your goal is not achievable. JSHint will look for configuration in your .jshintrc or in your case your Gruntfile. The only other overrides you can make is locally in the individual file.

If you are relying on global variables you should disable that setting, override to specify each of the variables either in your config or each file, or put them all in a name space.

I highly recommend switching to a module pattern and disallow anything leaking into the global scope

Munter
  • 1,079
  • 5
  • 7
  • How does your comment relate to my answer? OP question was "Is this goal achievable", answer: "No" – Munter Jan 04 '15 at 22:26
  • OP is relying on global variables, which is not desirable. Sine this is the whole reason why jshint is warning, and this is what the question is about, I find it relevant to point out that the proper solution would not be to hack jshint, but to encapsulate properly. That, or disable the check for implicit globals by setting `undef: false`, which would lower the code quality imo – Munter Jan 04 '15 at 22:38
  • Thanks for your reply. I'm actually using a module pattern. However, that module's name still in global scope. And I will use that in one of the JS files instead of in an html file (at least as the access point). So eventually JSHint will complaint the JS file that the module's name is used. I'll use the workaround "globals" at the moment. Since there's one file access that, I'll put it into individual file instead. – Mao Jan 05 '15 at 01:54
0

You will need to tell JSHint in file_two.js about the globals it uses

/* global Foo, Bar */

for file_one.js you will get a message that Foo is defined but not used. So you need to tell JSHint that other files will make use of it

/* exported Foo */
zevero
  • 2,312
  • 21
  • 12