4

The following code is valid in ESLint with Google's style guide with one exception; the closure function Counter gets a no-unused-vars error when the script is checked using ESLint.

/**
 * Create a counter that is incremented and returned when called
 * @return {object} - incrementor function
 */
function Counter() {
  var _i = 0;

  /**
   * increment counter
   * @return {int} - The incremented integer
   */
  function _incrementor() {
    _i++;
    return _i;
  }

  _incrementor.incr = function() {
    this.call();
    return _incrementor;
  };

  _incrementor.val = function(val) {
    if (!arguments.length) { return _i; }
    _i = val;
    return _incrementor;
  };

  return _incrementor;
}

I would like to have this function (or one structure the same way) as a standalone script that I can include in my HTML and then call from a different script like so:

var count = Counter()
    .val(5);

count.incr() 
console.log(count.val())  // prints => 6

I have tried including /* exported Counter */ at the top of the script but the error persists. How do I silence/fix this error?

tayden
  • 570
  • 7
  • 20
  • According to [eslint.org](http://eslint.org/docs/rules/no-unused-vars.html) adding `/* export Counter */` should have worked, unless it's specifically for variables and not standalone functions. Also, closure is kind of irrelevant here since it's not an IIFE. – Sterling Archer Dec 10 '15 at 18:29
  • IIFE? In reality, I'm using functions like this to create reusable D3 chart generators. This is just a simple example. – tayden Dec 10 '15 at 18:30
  • 1
    Why no just put `//eslint-disable-line no-unused-vars` to ignore the error. And here is the description on when `exported` will not work http://eslint.org/docs/rules/no-unused-vars.html#exporting-variables – Gyandeep Dec 10 '15 at 18:58
  • Disabling the line works to suppress the error, but I'd rather just fix it properly if possible. I have double checked that the node and commonjs environment options in my .eslintrc are false and that ecmaFeatures.modules is also false but still get the error. – tayden Dec 10 '15 at 19:09
  • I created the scenario locally what you have and I was not able to reproduce the issue. I used eslint 1.10.3. I made sure I didnt have node and commenjs or modules setup. Can you move this code into a separate file and run eslint on this directly? – Gyandeep Dec 10 '15 at 19:18
  • Moved the script to a new file and a new location. I ran `eslint --init` and chose the google style guide. My .eslintrc.js file looks like this: `module.exports = { ecmaFeatures: { modules: false }, env: { node: false, commonjs: false }, extends: 'google' };` The error is still there. When you tried it, did you do a `eslint --init`? Perhaps it's something in the google defaults that is triggering the error – tayden Dec 10 '15 at 19:53
  • Did u add `/* exported Counter */` on top of the file? whats the eslint version? – Gyandeep Dec 10 '15 at 20:06
  • Yes I did. Using version 1.10.3. Thanks for the help btw. – tayden Dec 10 '15 at 20:13
  • Trying running with `--debug` flag to see the correct `.eslintrc` files are getting picked up. Also look for any other red flags. Also can u share the exact file you are trying to lint using fiddle. The new file where you moved the script to. that one. – Gyandeep Dec 10 '15 at 20:13

2 Answers2

2

Explicitly adding Counter to the global scope silences this error and prevents errors that may occur as a result of the implicit global scope used in the question.

/**
 * Create a counter that is incremented and returned when called
 * @return {object} - incrementor function
 */
this.Counter = function() {
  var _i = 0;

  /**
   * increment counter
   * @return {int} - The incremented integer
   */
  function _incrementor() {
    _i++;
    return _i;
  }

  _incrementor.incr = function() {
    this.call();
    return _incrementor;
  };

  _incrementor.val = function(val) {
    if (!arguments.length) {
      return _i;
    }
    _i = val;
    return _incrementor;
  };

  return _incrementor;
};
tayden
  • 570
  • 7
  • 20
1

Here's some options for telling the linter to allow a global Counter variable:

Option #1: Add this comment to the top of the js file when you need to use the global variable:

/* globals Counter */

Option #2: Add the variable name to the globals property in your eslint configuration file:

// eslintrc.js

module.exports = {
  // ...

  globals: {
    'Counter': true
  }
}

See ESLint documentation here for more info.

Note: you can also use the env property in your config file for predefined sets of globals like: browser (ie. localStorage), jquery, node, etc.). See here.

prograhammer
  • 20,132
  • 13
  • 91
  • 118