I use ESLint from Node.js to check my code and it seems not to catch ReferenceErrors. Here is a minimal example, mre.js
:
console.log(obj);
let obj = 2;
When I run ESLint, I get no warnings:
$ ./node_modules/.bin/eslint mre.js
I updated ESLint and confirm it is the latest version (9.2.6):
$ npm update eslint
$ npm info eslint version
9.26.0
How can I make ESLint catch ReferenceErrors, or what is a linter that catches them?
You should enable the no-undef
and no-use-before-define
rule. The two should capture most cases where you try to access something that can lead to a ReferenceError.
no-use-before-define
Note that no-use-before-define does catch some cases where there will not be a reference error, like:
console.log(foo); //error here
var foo = 42;
fn(); // error here
function fn() {}
Of the two, the var
example is probably OK to have an error: first, you should not be using var
and second, even when using it, trying to reference it before assignment suggests something wrong with the code structure or logic.
The function example can be arguable. Some style guides insist on functions being defined first before used, others may actually prefer them at the end.
The no-use-before-define rule has options determining what is allowed to be referenced before definition. To allow this for functions, the option is called functions
, so it can be configured like this:
{
"no-use-before-define": [
"error",
{
"functions": true
}
]
}
no-undef
The rule straight up disallows using something that is not known to exist. That is some times overly strict - if you use scripts on a page like:
<script src="a.js"></script>
<script src="b.js"></script>
Where a.js creates a global and b.js tries to use it, then ESLint will have no knowledge of that and will flag a problem in b.js. In modern JavaScript you should be using modules and importing things from other modules. That immediately resolves this issue. But if still needed, you can specify globals in the configuration, this dealing with the no-undef
check. This might be useful in older code bases.
Some built-ins might not be known to ESLint, like (commonly) console
. But there might be other built-in globals that are exposed by the environment (e.g., in Node.js) or a framework (e.g., Mocha). ESLint also has predefined collections of globals that can be included by mentioning the environment. For example, if you are linting Node.js code you can just include all globals related to it in the configuration, without having to define them one by one.