How and When to Specify Globals in Eslintrc

The ESLint docs have a short section that gives the fundamentals of configuring global variables in a .eslintrc file.

However, the docs do not answer the following questions:

  • When and why would I want to define global variables in ESLint?
  • What errors occur when I try to use global vars differently than they are configured?

Additionally, I asked the following questions:

  • Can I configure global variables imported from JavaScript libraries?
  • Can I ‘turn off’ a subset of functions within a globally available object?
  • Can I ‘ban’ a variable name (global or local)?
  • How do I initialize the value of a ‘readonly’ global variable?

To answer these questions, I defined the below globals.

In most of my articles, I link to a Code Sandbox. With my ESLint articles, I simply screenshot my configurations; my actual React code is nonsense because my goal is to break things ;).

Setup

I am using the AirBnB style guide and the .json extension for my .eslintrc file.

Relevant package.json devDependencies:

"@typescript-eslint/eslint-plugin": "^4.28.2",
"@typescript-eslint/parser": "^4.28.2",
"eslint-config-airbnb": "^18.2.1"

Full .eslintrc.json configuration:

{
    "env": {
        "browser": true,
        "es2021": true  //not listed in documentation
    },
    "extends": [
        "plugin:react/recommended",
        "airbnb"
    ],
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
        "ecmaFeatures": {
            "jsx": true
        },
        "ecmaVersion": 12,
        "sourceType": "module"
    },
    "plugins": [
        "react",
        "@typescript-eslint"
    ],
    "rules": {
        "linebreak-style": 0,
        "no-use-before-define": "off"
    },
    "globals": {
        "var1": "readonly",
        "var2": "writable",
        "console": "off",
        "window": "off",
        "lodash": "off",
        "Promise": "off",
        "const": "off"
    }
}

This is a fairly minimal .eslintrc file, other than having quite a few globals configured. line-break: 0 is a setting I need as a windows user. no-use-before-define: off is a hack to eliminate garbage errors about importing React.

Readonly and Writable Globals

Why should we bother declaring globals in our .eslintrc file as readonly or writable? So that we can use them without violating ESLint rules such as no-undef.

Let’s take a look at assigning values to three variables, the first of which is readonly, the second is writable, and the third is not declared in our .eslintrc file as a global:

var1 = 5; //  Error: Read-only global 'var1' should not be modified. eslint (no-global-assign)
var2 = 6;
var3 = 7; // Error: 'var3' is not defined. eslint (no-undef)
  • var1 is readonly and triggers the ‘no-global-assign‘ error.
  • var2 is fine to modify and triggers no error.
  • var3 is not declared as any kind of global and triggers the no-undef error.

The no-undef error is intended to prevent typos in variables and accidental global variable creation. As the example in the 'no-undef‘ documentation shows, functions can also be declared as globals.

So how do we initialize the value of a readonly global? I don’t think we’re supposed to. Instead, here’s two use cases for globals:

  • If globals are defined in imported scripts, those globals could then be modified if they are not readonly. I think this was a problem before es6 modules were commonly used (please leave a comment if I have this wrong).
  • Globals used to be used to protect global JS objects (i.e. JSON or RegExp). However, this is not needed as these objects are recognized by ESLint as being globals.

If you did want to specify a global in your .eslintrc file and then initialize it’s value in your code, one hack is to disable rules for a single line using eslint-disable. I’m not recommending this, I’m simply saying it is possible.

Other than protecting known globals, why might you want to disable a global values? A possible situation is that your team has an internal rule against using certain objects, like console (how often do these get accidentally committed :)).

Turning Off Global Variables

For my next test, I set console and window globals to off. These are Web API objects, not actually a part of JavaScript.

I then added the following code in a function:

window.alert('HEY!!');// 'window' is not defined. eslint (no-undef)
console.log('test');// 'console' is not defined. eslint (no-undef)

The comments are the errors that ESLint generated.

These behaved as expected. The app won’t compile when window and console are ‘off’ but those objects are referenced in the code. It’s like the compiler simply becomes unaware of them.

Other Miscellaneous Tests

For my final tests, I set Promise, lodash, and const to ‘off’. The lodash and const tests were nonsensical, just to see what would happen. The Promise test is actually straight from the ESLint docs.

The result of setting these globals to ‘off’: absolutely nothing.

First, let’s discuss Promise. It was still usable after being set to ‘off’. I believe that the ESLint docs are simply out of date and in the past it was possible to disable JavaScript global objects.

Now, however, we can no longer disable them. Also, if I try to reassign Promise, i.e. Promise = 'abc', I get the following ESLint error: Read-only global 'Promise' should not be modified. (eslint no-global-assign). This occurs regardless of how I set the global Promise value. Also, this occurs for all ‘Standard built-in JS objects‘.

Lodash is a third-party library I imported in my JSX file. When I import lodash, I have given it a namespace. Therefore it is not a global and I can use it without problem.

// executes properly
lodash.partition([1, 2, 3, 4], (element) => element < 1);

Finally, I set "const": "off" simply to see what would happen with reserved words. Absolutely nothing happened!

Here’s a few final pieces of information I discovered:

  • There are more environments that can be specified than just the (outdated?) list in the docs
  • If you want to disable a certain function on an object, i.e. window.alert, without disabling the entire window object, you need to create a custom rule.

Resources

Do you have lots of ESLint errors that need to be fixed? Fix as many as possible automatically with the ESLint fix command.

Installing the AirBnB style guide also installs an accessibility plugin called jsx-a11y. Here’s how to use eslint-plugins-jsx-a11y to make your site more accessible.

Share this post:

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.