eslint-plugin-import icon indicating copy to clipboard operation
eslint-plugin-import copied to clipboard

Webpack resolver looks for custom webpack config in packages with jsnext:main

Open tf opened this issue 9 years ago • 20 comments

With a .eslintrc like

"settings": {
  "import/resolver": {
    "webpack": {
      "config": "webpack.karma.config.js"
    }
  }
},

when I import

import {takeEvery} from 'redux-saga';

I get the error

 Cannot find module '/path/to/project/node_modules/redux-saga/webpack.karma.config.js

When I remove the jsnext:main entry from the package.json inside node_modules/redux-saga, the error goes away. So I guess the plugin is somehow trying to find a Webpack config inside redux-saga to load resolve configuration for ES6 files? This might be fine, looking for my custom Webpack config does not make sense, though.

tf avatar Nov 14 '16 15:11 tf

Did you tried ./webpack.karma.config.js?

k15a avatar Nov 14 '16 17:11 k15a

@k15a Prefixing the path with ./ does not change anything.

tf avatar Nov 14 '16 18:11 tf

I'm using semantic-ui-react and encountered the exact same issue. https://github.com/Semantic-Org/Semantic-UI-React/commit/1911865b60230eb10e3834dd3e2a95ed9a69695b

Voxis avatar Jan 31 '17 20:01 Voxis

Can corroborate. Our workaround was to create a symlink with the default name that targets the desired custom config, e.g.,

webpack.config.js -> karma.webpack.config.js

SpainTrain avatar Feb 02 '17 13:02 SpainTrain

I found a workaround for this problem by converting my ".eslintrc" into a ".eslintrc.js" and use path.resolve as follow:

var path = require('path');

module.exports = {
  settings: {
    'import/resolver': {
      webpack: {
        config: path.resolve("./webpack.config.dev.js")
      }
    }
  },

gwleclerc avatar Feb 09 '17 23:02 gwleclerc

@gwleclerc Tried your suggestion and didn't work for me

philostler avatar Mar 23 '17 21:03 philostler

Same issue here when using react-phone-number-input.

arabold avatar Jul 22 '17 14:07 arabold

Perhaps this can be solved by mutating the configuration when the plugin first gets it, converting relative paths to absolute paths.

Ideally, it would do the conversion using the absolute path of the configuration file.

wmertens avatar Aug 17 '17 13:08 wmertens

I tried putting the following line at https://github.com/benmosher/eslint-plugin-import/blob/master/resolvers/webpack/index.js#L65:

      if (configPath !== settings.config) settings.config = configPath

however, while that fixes CLI usage, it doesn't fix it in the editor. The problem is that there are many invocations, each having to do fix-up on first invacation, and somehow in my editor the node_module is the first invocation.

wmertens avatar Aug 17 '17 13:08 wmertens

I may have jumped the gun a bit with the PR above (variable names are confusing!)...

So my next question becomes, why is eslint trying to resolve those files anyway when (by default) it should ignore any files in node_modules?

By logging out the source and file passed into the resolver, I can see that it is attempting to resolve imports from within files in node_modules:

// Just showing the last two logs before the error
{ file: 'my-project/src/store/modules/index.js',
  source: 'react-router-redux' }
{ file: '/my-project/node_modules/react-router-redux/es/index.js',
  source: './reducer' }

Billy- avatar Jan 05 '18 01:01 Billy-

eslint-plugin-import most definitely does not ignore files in node_modules, because it's trying to verify the exports that you're importing from there. Separately, webpack may alias some of those out, so the resolver needs to run on them.

ljharb avatar Jan 05 '18 01:01 ljharb

Ah, I see. So would a valid fix for this issue be to simply check if we're in a node_module, and if so, ignore the configPath setting?

I think it's fair to say that when setting a configPath, you only want it to apply to your code, not any dependencies, right?

Billy- avatar Jan 05 '18 01:01 Billy-

Although I guess that would lead to inconsistent behaviour between absolute paths and relative, where absolute paths would always resolve a webpack config, relative ones would not in this case...

If you agree with my previous comment, would you also agree that it should apply to all cases (that is, if we're in a dependency; ignore configPath)?

Billy- avatar Jan 05 '18 01:01 Billy-

If it helps I'm also seeing this issue - there's a simple repository here showing the error:

https://github.com/cjpete/redux-saga-import-issue

cjpete avatar Jan 05 '18 11:01 cjpete

@Billy- wouldnt this proposed solution work in clean manner?

Perhaps this can be solved by mutating the configuration when the plugin first gets it, converting relative paths to absolute paths.

Andarist avatar Jan 05 '18 21:01 Andarist

I've successfully narrowed down the problem (at least for redux-saga) to the reexports being used:

export { foo } from './internal';

It seems that this plugin follows them, tries to resolve ./internal, but to resolve it it tries to apply a webpack config rules. It tries to resolve a webpack config, but to find it it uses a relative path and since it's looking at a package in node_modules we have a problem.

On the other hand 'manual' reexports are treated as safe:

import { foo } from './internal';
export { foo }

and it doesn't try to dive into ./internal in such case.

I'd still advocate for the simplest solution - just resolve config path once to an absolute path and be done with it, WDYT @ljharb ?

Andarist avatar Jan 06 '18 16:01 Andarist

I’m not sure i know enough about it to decide - i prefer to avoid webpack aliasing, personally.

It’s certainly worth a PR if tests can be made to pass.

ljharb avatar Jan 06 '18 16:01 ljharb

@Andarist I suppose yes it works, although as mentioned there is a caveat in that if the first file to be resolved is a node_module it doesn't work. I also think that mutating in this way is a bit of an antipattern..

wouldnt this proposed solution work in clean manner?

Billy- avatar Jan 06 '18 17:01 Billy-

per discussion in #995: need to enhance resolver spec to include the linting file in order to properly load webpack config relative to the linting file and not deep imports

benmosher avatar May 07 '18 00:05 benmosher

@gwleclerc your workaround works for me :) Had a yaml before, changed to .eslintrc.js with usage of path module and it worked.

aibolik avatar Apr 09 '19 10:04 aibolik