Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

eslint-import-resolver-webpack don't work for resolved paths #352

Closed
ideal-life-generator opened this issue May 21, 2016 · 80 comments
Closed
Labels

Comments

@ideal-life-generator
Copy link

ideal-life-generator commented May 21, 2016

.eslintrc

{
  "parser": "babel-eslint",
  "extends": "airbnb",
  "plugins": ["import"],
  "settings": {
    "import/resolver": "webpack"
  },
  "env": {
    "browser": true
  }
}

webpack.config.js

...
  resolve: {
    root: path.resolve('src'),
    extensions: ['', '.js', '.scss'],
    modulesDirectories: ['node_modules'],
  },
...

src/index.js

import routes from 'routes';
import 'scss/index.scss';

in console:

Error - Unable to resolve path to module 'routes'. (import/no-unresolved)
Error - Unable to resolve path to module 'scss/index.scss'. (import/no-unresolved)
@benmosher
Copy link
Member

Questions:

  • what version of the Webpack resolver?
  • is your webpack.config.js a sibling to the nearest ancestor package.json?
  • can you provide the whole Webpack config?

@ideal-life-generator
Copy link
Author

ideal-life-generator commented May 23, 2016

The test project is placed on https://github.com/must-be-perfect/searchresults/tree/version-0.
It's looks like something is wrong.

@benmosher
Copy link
Member

Nothing obvious at a glance...

@chadi-kazan
Copy link

i am having the same problem.
Using version 0.2.5 of the webpack resolver which is under a directory that's a sibling of package.json

@ideal-life-generator
Copy link
Author

Maybe is because airbnb? It also use this module.

@XVincentX
Copy link

I am facing the same issue and I have no idea why!

@chadi-kazan
Copy link

not sure it's coz of that. my eslint config extends google's..

@XVincentX
Copy link

Mine is extending airbnb

@ChristianHersevoort
Copy link

i have the same issue, versions:

webpack: 1.13.1
eslint-plugin-import: 1.8.1
eslint-import-resolver-webpack: 0.2.5

@benmosher
Copy link
Member

I just released 0.3.0 of the Webpack resolver yesterday (behind "next" tag).

Can you see if that fixes it? I still don't understand the issue, but that version uses Webpack's actual resolver under the covers.

@XVincentX
Copy link

XVincentX commented Jun 2, 2016 via email

@benmosher
Copy link
Member

benmosher commented Jun 2, 2016

Actually, just published v0.3.1(tag "next") that has debug logging built in (ref: #300), try calling ESLint from a terminal as follows:

DEBUG=eslint-plugin-import:* $(npm bin)/eslint src/jsx/redux/store.js

I would try linting a single file; the output is pretty verbose but hopefully will identify the issue (or at least disqualify bad config).

@ideal-life-generator
Copy link
Author

ideal-life-generator commented Jun 2, 2016

for me is fixed

no, sorry, have the same issue

@benmosher
Copy link
Member

Can you run with the debug ENV var set as I described above and paste the output?

@baldurh
Copy link

baldurh commented Jun 7, 2016

I’m having the same problem. Seems to happen when I use eslint-config-airbnb versions 8.0.0 and 9.0.1

@NorfAlrin
Copy link

@benmosher I was having the same issue and after enabling the debug ENV I found that 'eslint-import-resolver-webpack' was failing to resolve the import statements in my webpack.config.js file.

_SyntaxError: Unexpected token import
at Object.exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:513:28)
at Object.Module._extensions..js (module.js:550:10)
at Module.load (module.js:458:32)
at tryModuleLoad (module.js:417:12)
at Function.Module._load (module.js:409:3)
at Module.require (module.js:468:17)
at require (internal/module.js:20:19)
at Object.exports.resolve (C:\Dev\PhotosApp\node_modules\eslint-import-resolver-webpack\index.js:56:21)
at v2 (C:\Dev\PhotosApp\node_modules\eslint-plugin-import\lib\core\resolve.js:122:23)
Tue, 07 Jun 2016 13:21:03 GMT eslint-plugin-import:resolver:webpack Using config: {}
Tue, 07 Jun 2016 13:21:03 GMT eslint-plugin-import:resolver:webpack Config path from settings: build/webpack.config.js
Tue, 07 Jun 2016 13:21:03 GMT eslint-plugin-import:resolver:webpack Config path resolved to: C:\Dev\PhotosApp\build\webpack.config.js
Tue, 07 Jun 2016 13:21:03 GMT eslint-plugin-import:resolver:webpack Error during config lookup: C:\Dev\PhotosApp\build\webpack.config.js:1
(function (exports, require, module, __filename, _dirname) { import webpack from 'webpack';

I've "solved" this by creating a dummy web pack with just the resolve.root set.
This has allowed the relative paths to resolve correctly but this isn't really a good option.
Is there some way i can use import * from '*' in my web pack file and have 'eslint-import-resolver-webpack' work with that file?

@benmosher
Copy link
Member

If you name the file with.babel.js as its extension, the plugin will use the nearest Babel to pre-compile your config. This should match Webpack's behavior.

@jsdf
Copy link

jsdf commented Jun 9, 2016

I encountered an issue like this due to the fact that our webpack config was building some absolute paths using path.resolve, which implicitly uses process.cwd().

I fixed the issue by ensuring that the webpack config could resolve all necessary paths regardless of what process.cwd was (by resolving them relative to __dirname).

@johnhforrest
Copy link

Also having this problem with version 0.3.0 and airbnb rules.

I tried jsdf's recommendation of removing any path.resolve references from the config and that didn't work for me.

Here's what my resolve looks like in my webpack.config.js file:

config.resolve = {
  root: [client],
  alias: {
    'css': join(client, 'styles'),
    'containers': join(client, 'containers'),
    'components': join(client, 'components'),
    'utils': join(client, 'utils')
  }
};

And here's my .eslintrc:

{
  "extends": "airbnb",
  "settings": {
    "import/resolver": "webpack"
  },
  "env": {
    "browser": true
  }
}

@benmosher
Copy link
Member

@johnhforrest can you install v0.3.1 of the webpack resolver and run eslint in a terminal with

DEBUG=eslint-plugin-import:* eslint [.. one file ..]

It will spit out a bunch of (hopefully useful) debug logging. I recommend that you only run it against one file at a time or it will get lost in a wall of log messages.

@benmosher
Copy link
Member

I'm closing this on account of it sortof meandering around.

If any of y'all are able to run with DEBUG=eslint-plugin-import:* and get some output, please open a new specific issue.

@smkhalsa
Copy link

@benmosher here's what I get when I run DEBUG=eslint-plugin-import:* on my app directory...

Cannot find module 'eslint-config-airbnb'
Referenced from: /Users/smkhalsa/code/kundalini-yoga/.eslintrc
Error: Cannot find module 'eslint-config-airbnb'
Referenced from: /Users/smkhalsa/code/kundalini-yoga/.eslintrc
at Object.ModuleResolver.resolve (/usr/local/lib/node_modules/eslint/lib/util/module-resolver.js:75:19)
at resolve (/usr/local/lib/node_modules/eslint/lib/config/config-file.js:479:33)
at load (/usr/local/lib/node_modules/eslint/lib/config/config-file.js:496:24)
at /usr/local/lib/node_modules/eslint/lib/config/config-file.js:392:36
at Array.reduceRight (native)
at applyExtends (/usr/local/lib/node_modules/eslint/lib/config/config-file.js:363:28)
at Object.load (/usr/local/lib/node_modules/eslint/lib/config/config-file.js:530:22)
at loadConfig (/usr/local/lib/node_modules/eslint/lib/config.js:64:33)
at getLocalConfig (/usr/local/lib/node_modules/eslint/lib/config.js:136:23)
at Config.getConfig (/usr/local/lib/node_modules/eslint/lib/config.js:263:22)

@benmosher
Copy link
Member

@smkhalsa: so looks like there's another problem ATM, with your Airbnb shared config?

@frodosamoa
Copy link

@smkhalsa you might need to run ./node_modules/.bin/eslint instead of just eslint

@arkaitzgarro
Copy link

arkaitzgarro commented Aug 2, 2016

I solved that problem providing absolute path for webpack config file:

'import/resolver': {
  webpack: {
    config: path.join(__dirname, 'webpack.config.js')
  }
}

Notice that this solution forces to use js format for eslint.

@zhanghaowx
Copy link

zhanghaowx commented Aug 19, 2016

I also have the same problem when running eslint from command line. (In Atom I use linter-eslint plugin and everything works fine)

@jsdf 's solutions doesn't work for me either.


Here is what I do

By change

    "settings": {
        "import/resolver": "webpack"
    },

to

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

I solved some import/no-unresolved on dependencies installed inside node_modules. But still all resolved paths are not recognized.

Finally I tried the local eslint instead of the global one and everything works fine now. Both in v3.3.0.
So instead of

eslint --config .eslintrc.js .

do

./node_modules/eslint/bin/eslint.js --config .eslintrc.js .

The cause may still be what @jsdf described, but I have to work around in another way.

@sompylasar
Copy link
Contributor

By the way, which module implements the magic .babel.js handling? That's obviously not Node itself, so if my eslintrc is called from Atom Linter it won't have the necessary environment for the magic to happen.

@ljharb
Copy link
Member

ljharb commented Apr 6, 2017

That's webpack itself; I'd assume eslint would do it too.

@anisimovyuriy
Copy link

npm install --save-dev eslint-import-resolver-webpack - resolved the issue!

@benmosher
Copy link
Member

benmosher commented May 25, 2017

By the way, which module implements the magic .babel.js handling?

@sompylasar: the Webpack resolver does it to match Webpack proper (which also does it). so it ought to work in any ESLint integration environment.

@sompylasar
Copy link
Contributor

@benmosher ESLint does not rely on Webpack, so does not Atom Linter, so when Atom Linter calls ESLint, there is no Webpack magic built in.

@benmosher
Copy link
Member

clarification: eslint-import-resolver-webpack implements the aforementioned magic.

So: Atom Linter => ESlint => eslint-plugin-import => eslint-import-resolver-webpack => ✨magic✨

@iamgutz
Copy link

iamgutz commented Jun 23, 2017

resolved by adding the webpack resolver plugin to the eslintrc config and CHANGING in the webpack config files require path in ES5 style.

// webpack.config.dev.js
const path = require('path'); // instead of import path from 'path'

// .eslintrc
"settings": {
      "import/resolver": {
        "webpack": {
          "config": "webpack.config.dev.js"
        }
      }
    }

// package.json
"eslint-import-resolver-webpack": "^0.8.2",

@kettanaito
Copy link

kettanaito commented Jun 23, 2017

I might as well be wrong, but it should be possible to use ES6 syntax with Webpack configuration if you rename it to webpack.babel.js. This should not throw any errors from configuration validation part of eslint's Webpack resolver.

@iamgutz
Copy link

iamgutz commented Jun 27, 2017

@asdine your solution works! Thanks!

@bramschulting
Copy link

I'm running into this issue as well, but only when viewing files in Atom.

When I run node_modules/.bin/eslint src/js/app/modules/sectionsPage/containers/SectionTileContainer.js, everything works fine. But in Atom I get import/no-unresolved errors.

If I run DEBUG=eslint-plugin-import:* $(npm bin)/eslint src/js/app/modules/sectionsPage/containers/SectionTileContainer.js I can see the import/resolve fail, but I don't understand why. This is my output (I cut off a bit at the end):

eslint-plugin-import:resolver:node Resolving: +0ms stores/AuthStore from: /Users/bramschulting/projects/web-client/src/js/app/modules/sectionsPage/containers/SectionTileContainer.js
eslint-plugin-import:resolver:node resolve threw error: +4ms Error: Cannot find module 'stores/AuthStore' from '/Users/bramschulting/projects/web-client/src/js/app/modules/sectionsPage/containers'
  at Function.module.exports [as sync] (/Users/bramschulting/projects/web-client/node_modules/resolve/lib/sync.js:36:11)
  at Object.exports.resolve (/Users/bramschulting/projects/web-client/node_modules/eslint-import-resolver-node/index.js:19:28)
  at v2 (/Users/bramschulting/projects/web-client/node_modules/eslint-module-utils/resolve.js:79:23)
  at withResolver (/Users/bramschulting/projects/web-client/node_modules/eslint-module-utils/resolve.js:84:16)
  at fullResolve (/Users/bramschulting/projects/web-client/node_modules/eslint-module-utils/resolve.js:101:22)
  at relative (/Users/bramschulting/projects/web-client/node_modules/eslint-module-utils/resolve.js:46:10)
  at resolve (/Users/bramschulting/projects/web-client/node_modules/eslint-module-utils/resolve.js:172:12)
  at checkSourceValue (/Users/bramschulting/projects/web-client/node_modules/eslint-plugin-import/lib/rules/no-unresolved.js:29:50)
  at checkSourceValue (/Users/bramschulting/projects/web-client/node_modules/eslint-module-utils/moduleVisitor.js:29:5)
  at EventEmitter.checkSource (/Users/bramschulting/projects/web-client/node_modules/eslint-module-utils/moduleVisitor.js:34:5)
eslint-plugin-import:resolver:webpack Config path from settings: /Users/bramschulting/projects/web-client/webpack.config.js +0ms
eslint-plugin-import:resolver:webpack Config path resolved to: /Users/bramschulting/projects/web-client/webpack.config.js +1ms
eslint-plugin-import:resolver:webpack Using config:  { cache: true,
debug: true,
devtool: 'source-map',
resolve:
 { root: '/Users/bramschulting/projects/web-client',
   extensions: [ '', '.js', '.jade' ],
   modulesDirectories:
    [ 'node_modules',
      'src/js/app',
      'src/js/vendor_modules',
      'tests/mock' ],
   alias:
    { environment: '/Users/bramschulting/projects/web-client/src/js/app/config/env/local.js',
      byebye: '/Users/bramschulting/projects/web-client/src/js/app/libs/byebye/byebye.js',
      q: '/Users/bramschulting/projects/web-client/src/js/app/libs/q.js',
      templates: '/Users/bramschulting/projects/web-client/src/templates',
      backbone: 'exoskeleton/exoskeleton',
      'appboy-web-sdk': 'appboy-web-sdk/appboy.core.min.js',
      'react/lib/ReactMount': 'react-dom/lib/ReactMount' } },
...

The line which failes is:

import AuthStore from 'stores/AuthStore';

But that is located in /Users/bramschulting/projects/web-client/src/js/app/stores/AuthStore.js, so the webpack resolve config should be correct, right?

Does anyone have an idea what's going on? This issue is driving me nuts 🔩

@sompylasar
Copy link
Contributor

@bramschulting If you look into the error stacktrace, it is coming from eslint-import-resolver-node, while you expect it to use eslint-import-resolver-webpack. Seems you have configured both, and node takes precedence over webpack.

@bramschulting
Copy link

@sompylasar Oh right, thanks! That's due to a config we're extending (airbnb). Is there a way to disable this? I can manually overwrite it, but I'd prefer to disable it (as it's redundant) or 'use' the webpack config for the node resolver. Is that possible?

@sompylasar
Copy link
Contributor

@bramschulting
I use it this way in my .eslintrc.js:

  "settings": {
    "import/ignore": [
      "node_modules",
      "\\.(scss|less|css)$",
    ],
    "import/resolver": {
      "node": {
        "moduleDirectory": [
          "./src/webapp",
          "./src/api",
          "./src/server",
          "./src/common",
        ],
      },
      "webpack": {
        "config": "./webpack/configForEslintImportResolver.js",
      },
    },
  },

@bramschulting
Copy link

@sompylasar yeah I was thinking of this too. But the downside of this is that you still have to define the moduleDirectory in two locations (in .eslintrc and your webpack config).

@sompylasar
Copy link
Contributor

@bramschulting Right. Well, I didn't go extra mile here, but you can require that info from a separate JS file 1) from .eslintrc.js to give the module roots to eslint-import-resolver-node and 2) from the webpack config for the eslint-import-resolver-webpack to give the module roots to it.

@bramschulting
Copy link

@sompylasar OK, I'm running into another issue 🙈 I'm getting errors when importing files that have an alias in my webpack config, because the node-resolver tries to resolve them first I think.

I've been looking at this module to figure out where the order is being determined, but I can't seem to find it. Could you give me some pointers? I'd like to make a PR which allows for setting the resolve order, maybe like this:

    "import/resolver": {
      "order": ["webpack", "node"],
      "webpack": {
        "config": "webpack/config.js"
      }
    }

That would fix all the problems I mentioned, right?

@sompylasar
Copy link
Contributor

@bramschulting The order of iterating over the configured resolvers is defined by the Map iteration order: https://github.com/benmosher/eslint-plugin-import/blob/dc3609f895f5ad390d88fd9925dce40960117930/utils/resolve.js#L92-L97
But from the code, the import/resolver config could be an array:
https://github.com/benmosher/eslint-plugin-import/blob/dc3609f895f5ad390d88fd9925dce40960117930/utils/resolve.js#L117-L120

I assume it could look like this, but I haven't tested it:

    "import/resolver": [
      {
        "webpack": {
          "config": "./webpack/config.js"
        }
      },
      {
        "node": {
          "moduleDirectory": [
            "whatever"
          ]
        }
      }
    ]

I also recommend to write relative paths explicitly with ./, to make them more visible (also someone reported that the path without ./ didn't work for them, but I doubt this is true).

@sompylasar
Copy link
Contributor

sompylasar commented Jul 20, 2017

The array shape of import/resolver is not documented, by the way, but that is a documentation issue: https://github.com/benmosher/eslint-plugin-import/blob/ccd93942a0b9f59f1b698672ba167ece1aa9f5f1/README.md#resolvers
CC @benmosher

@gricard
Copy link

gricard commented Jun 1, 2018

Just wanted to thank @sompylasar for his example of ignoring node_modules. That resolved an issue that broken eslint for us. Thank you!!

@sompylasar
Copy link
Contributor

@gricard You're welcome!

@aeolusheath
Copy link

as @arkaitzgarro said, it works for me.

but I didn't use path.

config: path.join(__dirname, 'webpack.config.js')

my .eslintrc.js :

module.exports = {
 //... other configs
  plugins: [
    'vue',
    'import'
  ],
  settings: {
    "import/resolver": {
        "webpack": {
            "config": "./build/webpack.base.conf.js"
        }
    }
  },
}

files location:

|-- package.json
|-- .eslintrc.js
|-- build
    |-- webpack.base.conf.js

@LittleBreak

This comment has been minimized.

@qbalin
Copy link

qbalin commented Jul 21, 2020

What did it for me was to move extensions: ['*', '.js', '.jsx'] from module.rules[0].resolve to the root resolve field (in webpack.config.js). .jsx files were problematic.

Before:

  resolve: {
    alias: {
      component: path.resolve(__dirname, 'frontend/component/'),
      store: path.resolve(__dirname, 'frontend/store/'),
      lib: path.resolve(__dirname, 'frontend/lib/'),
      context: path.resolve(__dirname, 'frontend/context/'),
    },
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /(node_modules)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env', '@babel/preset-react'],
            plugins: ['@babel/plugin-proposal-object-rest-spread'],
          },
        },
        resolve: {
          extensions: ['*', '.js', '.jsx'], // <-- This has to be moved up
        },
      },
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },

After:

  resolve: {
    alias: {
      component: path.resolve(__dirname, 'frontend/component/'),
      store: path.resolve(__dirname, 'frontend/store/'),
      lib: path.resolve(__dirname, 'frontend/lib/'),
      context: path.resolve(__dirname, 'frontend/context/'),
    },
    extensions: ['*', '.js', '.jsx'], // <-- Here, it works 
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /(node_modules)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env', '@babel/preset-react'],
            plugins: ['@babel/plugin-proposal-object-rest-spread'],
          },
        },
      },
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },

@moonjoungyoung
Copy link

@arkaitzgarro

Thank you so much. You solved my one-year problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests