babel / babel-eslint

:tokyo_tower: A wrapper for Babel's parser used for ESLint (renamed to @babel/eslint-parser)

Home Page:https://github.com/babel/babel/tree/main/eslint/babel-eslint-parser

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

babel-eslint not compatible with `no-unused-vars: [2, {vars: local}]`

kentor opened this issue · comments

Ok I have this setup:

❯ tree -a -I node_modules
.
├── A
│   ├── .eslintrc
│   └── a.js
├── B
│   ├── .eslintrc
│   └── b.js
└── package.json

A/.eslintrc:

---
rules:
  no-unused-vars: [2, {vars: local}]  # Allow defining globals

A/a.js:

var a = 1;

B/.eslintrc:

---
parser: babel-eslint

B/b.js:

var b = 2;

package.json:

{
  "dependencies": {
    "babel-eslint": "^3.1.19",
    "eslint": "^0.24.0",
    "esprima": "^2.4.0",
    "esprima-fb": "^15001.1.0-dev-harmony-fb"
  }
}

Running eslint on dir A and B gives the expected result:

❯ $(npm bin)/eslint A B

B/b.js
  1:4  error  b is defined but never used  no-unused-vars

✖ 1 problem (1 error, 0 warnings)

however, running it on dir B and A gives an additional unexpected error on a.js:

❯ $(npm bin)/eslint B A

B/b.js
  1:4  error  b is defined but never used  no-unused-vars

A/a.js
  1:4  error  a is defined but never used  no-unused-vars

✖ 2 problems (2 errors, 0 warnings)

This only happens when using babel-eslint as the parser for directory B. I've tried the default parser, esprima, and esprima-fb and it does not throw the error for a.js. The result shouldn't change given the order of directories given to eslint right?

commented

I don't think this would be a babel-eslint since it's only the parser and changes some tokens etc - It doesn't define any rules or anything. I'm not sure what happens when you try to lint 2 directories with different configs other than in http://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy - where it merges the config. Maybe that's what is happening here.

commented

@nzakas - this isn't really a babel-eslint issue right?

If it works OK with the default parser, and Esprima, then it must be a babel-eslint issue.

commented

Ok it's because no-unused-vars: [2, {vars: local}] isn't compatible with babel-eslint - nothing to do with different directories/configs. Just do $(npm bin)/eslint B with the babel-eslint parser and the rule and it will error.

commented

Ok after doing some more looking it seems like it's because we are doing opts.sourceType = "module"; for escope. Based on that I tried

ecmaFeatures:
    modules: true
rules:
  no-unused-vars: [2, {vars: local}]

and it also will error with the regular parser.

I see.. the monkey patching basically affects all subsequent linting. For now I can just change my script to switch the order to have the directory that uses babel-eslint be the last.

FWIW, Babel is probably going to get the ability to load ESLint rules rather than hacking around ESLint internal APIs and monkeypatching them.

What would be necessary in the ESLint side to prevent you from needing to monkey patch or otherwise load rules directly?

There's no way for people using Babel to ever use ESLint as a first class citizen. It'd mean putting all of this into ESLint core, escope etc.

Yikes! Okay, at some point I'll dig in and see what's going on there.

commented

Yeah that part is comment attachment, supporting no-unused-vars for es7 (decorators, comprehensions) and flow by changing escope, changing estraverse visitors

commented

I guess we'll just close this for now with the workaround being what @kentor said:

For now I can just change my script to switch the order to have the directory that uses babel-eslint be the last.