import-js / eslint-plugin-import

ESLint plugin with rules that help validate proper imports.
MIT License
5.52k stars 1.56k forks source link

import/named rule breaks when using a custom resolver since 2.10.0 #1078

Open ThiefMaster opened 6 years ago

ThiefMaster commented 6 years ago
[adrian@blackhole:/tmp/bug]> npm i eslint eslint-plugin-import redux
npm WARN saveError ENOENT: no such file or directory, open '/tmp/bug/package.json'
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN enoent ENOENT: no such file or directory, open '/tmp/bug/package.json'
npm WARN bug No description
npm WARN bug No repository field.
npm WARN bug No README data
npm WARN bug No license field.

+ eslint-plugin-import@2.11.0
+ redux@3.7.2
+ eslint@4.19.1
added 183 packages from 154 contributors in 3.603s

[adrian@blackhole:/tmp/bug]> cat > test.js
import {createStore} from 'redux';

[adrian@blackhole:/tmp/bug]> cat > .eslintrc.yml
parserOptions:
  sourceType: module

plugins:
  - import

settings:
  import/resolver: ./my-resolver

rules:
  import/named: error

[adrian@blackhole:/tmp/bug]> cat > my-resolver.js
module.exports = require('eslint-import-resolver-node');

[adrian@blackhole:/tmp/bug]> npx eslint test.js
unable to load resolver "./my-resolver".

[adrian@blackhole:/tmp/bug]> cat > test2.js
import {foo} from './test';
[adrian@blackhole:/tmp/bug]> npx eslint test2.js

/tmp/bug/test2.js
  1:9  error  foo not found in './test'  import/named

✖ 1 problem (1 error, 0 warnings)

As you can see, as soon as I named import something from redux, my custom resolver cannot be found anymore.

I've added a debug statement to node_modules/eslint-module-utils/resolve.js in requireResolver that dumps the sourceFile and the associated base dir, and I got this:

[adrian@blackhole:/tmp/bug]> npx eslint test.js
Trace: /tmp/bug/test.js /tmp/bug
    at requireResolver (/tmp/bug/node_modules/eslint-module-utils/resolve.js:156:11)
    at fullResolve (/tmp/bug/node_modules/eslint-module-utils/resolve.js:115:22)
    at relative (/tmp/bug/node_modules/eslint-module-utils/resolve.js:61:10)
    at resolve (/tmp/bug/node_modules/eslint-module-utils/resolve.js:181:12)
    at Function.ExportMap.get (/tmp/bug/node_modules/eslint-plugin-import/lib/ExportMap.js:290:38)
    at checkSpecifiers (/tmp/bug/node_modules/eslint-plugin-import/lib/rules/named.js:36:43)
    at listeners.(anonymous function).forEach.listener (/tmp/bug/node_modules/eslint/lib/util/safe-emitter.js:47:58)
    at Array.forEach (<anonymous>)
    at Object.emit (/tmp/bug/node_modules/eslint/lib/util/safe-emitter.js:47:38)
    at NodeEventGenerator.applySelector (/tmp/bug/node_modules/eslint/lib/util/node-event-generator.js:251:26)
Trace: /tmp/bug/node_modules/redux/es/index.js /tmp/bug/node_modules/redux
    at requireResolver (/tmp/bug/node_modules/eslint-module-utils/resolve.js:156:11)
    at fullResolve (/tmp/bug/node_modules/eslint-module-utils/resolve.js:115:22)
    at Function.relative (/tmp/bug/node_modules/eslint-module-utils/resolve.js:61:10)
    at remotePath (/tmp/bug/node_modules/eslint-plugin-import/lib/ExportMap.js:379:30)
    at captureDependency (/tmp/bug/node_modules/eslint-plugin-import/lib/ExportMap.js:408:15)
    at /tmp/bug/node_modules/eslint-plugin-import/lib/ExportMap.js:443:7
    at Array.forEach (<anonymous>)
    at Function.ExportMap.parse (/tmp/bug/node_modules/eslint-plugin-import/lib/ExportMap.js:424:12)
    at Function.ExportMap.for (/tmp/bug/node_modules/eslint-plugin-import/lib/ExportMap.js:331:25)
    at Function.ExportMap.get (/tmp/bug/node_modules/eslint-plugin-import/lib/ExportMap.js:293:23)
unable to load resolver "./my-resolver".

[adrian@blackhole:/tmp/bug]> npx eslint test2.js
Trace: /tmp/bug/test2.js /tmp/bug
    at requireResolver (/tmp/bug/node_modules/eslint-module-utils/resolve.js:156:11)
    at fullResolve (/tmp/bug/node_modules/eslint-module-utils/resolve.js:115:22)
    at relative (/tmp/bug/node_modules/eslint-module-utils/resolve.js:61:10)
    at resolve (/tmp/bug/node_modules/eslint-module-utils/resolve.js:181:12)
    at Function.ExportMap.get (/tmp/bug/node_modules/eslint-plugin-import/lib/ExportMap.js:290:38)
    at checkSpecifiers (/tmp/bug/node_modules/eslint-plugin-import/lib/rules/named.js:36:43)
    at listeners.(anonymous function).forEach.listener (/tmp/bug/node_modules/eslint/lib/util/safe-emitter.js:47:58)
    at Array.forEach (<anonymous>)
    at Object.emit (/tmp/bug/node_modules/eslint/lib/util/safe-emitter.js:47:38)
    at NodeEventGenerator.applySelector (/tmp/bug/node_modules/eslint/lib/util/node-event-generator.js:251:26)
Trace: /tmp/bug/test.js /tmp/bug
    at requireResolver (/tmp/bug/node_modules/eslint-module-utils/resolve.js:156:11)
    at fullResolve (/tmp/bug/node_modules/eslint-module-utils/resolve.js:115:22)
    at Function.relative (/tmp/bug/node_modules/eslint-module-utils/resolve.js:61:10)
    at remotePath (/tmp/bug/node_modules/eslint-plugin-import/lib/ExportMap.js:379:30)
    at captureDependency (/tmp/bug/node_modules/eslint-plugin-import/lib/ExportMap.js:408:15)
    at /tmp/bug/node_modules/eslint-plugin-import/lib/ExportMap.js:443:7
    at Array.forEach (<anonymous>)
    at Function.ExportMap.parse (/tmp/bug/node_modules/eslint-plugin-import/lib/ExportMap.js:424:12)
    at Function.ExportMap.for (/tmp/bug/node_modules/eslint-plugin-import/lib/ExportMap.js:331:25)
    at Function.ExportMap.get (/tmp/bug/node_modules/eslint-plugin-import/lib/ExportMap.js:293:23)

/tmp/bug/test2.js
  1:9  error  foo not found in './test'  import/named

As you can see, for test.js it now tries to resolve a file inside node_modules so of course the baseDir points to that package's directory, not my project directory.


I think the best option would be to try loading a relative resolver location from the directory where the eslint config is. I actually expected that to be the case in the tryRequire(name) case, but it turned out to be relative to the eslint-module-utils package directory, which seems to be wrong/pointless - why would there ever be a custom resolver in that location.

ThiefMaster commented 6 years ago

Apparently there were cases even before 2.10 where this problem showed up.