Hi, not sure if it is a bug. If no sorry.
I use a Webpack resolve condition:
resolve: {
alias: {
"pg-face": __dirname + '/src/pg-face/src/'
}
},
My includes look like:
import TableLine from 'pg-face/components/tables/TableLine'
And because of that I have the eslint report:
error 'pg-face' should be listed in the project's dependencies. Run 'npm i -S pg-face' to add it import/no-extraneous-dependencies
Have a nice day.
Ah, yeah, not so much a bug as a missing feature. 馃槄
It's tough to disambiguate "project" dependencies from node_modules dependencies ATM, so aliases may not play nicely with no-extraneous-dependencies.
Is this the same issue with externals? Seems odd that import/resolve: webpack will quiet no-unresolved but not no-extraneous-dependencies.
@simonbuchan I suspect that's true. externals has a similar property to aliases in that it results in more path-resolution magic than no-extraneous-dependencies is prepared to handle.
Though I wouldn't be surprised if certain (if not all) externals definitions look like core modules instead of dependencies, but I'm not sure.
Upon further reflection, this is another case of #479, should be solvable the same way.
eslint-plugin-import supports custom resolvers _(full list)_. Using eslint-import-resolver-webpack solved this problem for me.
I'm using eslint-import-resolver-webpack, and I'm still getting this error even though I have it defined in my module.resolve.root.
Even using eslint-import-resolver-webpack, it still not recognize webpack aliases and throw import/no-extraneous-dependencies
In my case, you should not use special prefix char like @assets but assets directly, or this warning will throw.
Another thing to keep in mind when using eslint-import-resolver-webpack:
Will look for webpack.config.js as a sibling of the first ancestral package.json, or a config parameter may be provided with another filename/path either relative to the package.json, or a complete, absolute path.
If multiple webpack configurations are found the first configuration containing a resolve section will be used. Optionally, the config-index (zero-based) setting can be used to select a specific configuration.
I discovered this recently when changing my webpack.config.js to export multiple (non-standard) configurations:
// specialized configurations for my custom setup
module.exports = {
config1: {},
config2: {},
};
instead of the webpack standard of :
// array of configurations
module.exports = [{}, {}];
// single configuration
module.exports = {};
which caused this error to reappear.
+1 still seeing issue
not working with webpack's externals options.
webpack 2.2
Not working for me either, webpack 2 (webpack correctly resolves the dependency)
root
package.json
webpack.config.base.js
eslintrc.js
someFolder
foo
"eslint": "^3.16.1",
"eslint-config-airbnb": "^14.1.0",
"eslint-import-resolver-webpack": "^0.8.1",
"eslint-plugin-import": "^2.2.0",
"eslint-plugin-jsx-a11y": "^3.0.2 || ^4.0.0",
module.exports = {
stats: { modules: false },
resolve: {
extensions: ['.js', '.jsx'],
alias: {
'foo': path.resolve(__dirname, `/someFolder/foo`),
},
},
}
module.exports={
extends: ['airbnb'],
parser: 'babel-eslint',
settings: {
'import/resolver': {
'webpack': {
'config': 'webpack.config.base.js'
}
}
},
}
import Something from 'foo'
import/no-extraneous-dependencies
import/no-unresolved
import/extensions
Everywhere on Github, "+1" comments are not helpful nor necessary. Please indicate your support by adding a thumbs up reaction to the original post.
I will now delete the existing +1 comments, and any future ones. Thanks!
eslint-import-resolver-webpack has worked pretty good with aliases in webpack 1.
After upgrade to webpack 2 problem happens again. Seems that webpack 2 is not supported yet.
Just fyi it might be an issue with webpack after all:
https://github.com/webpack/webpack/issues/4160
The following configuration works for me.
root
package.json
.eslintrc.json
config
webpack.config.base.js
src
components
component1.jsx
containers
container1.jsx
"eslint": "^3.19.0",
"eslint-config-airbnb": "^14.1.0",
"eslint-import-resolver-webpack": "^0.8.1",
"eslint-loader": "^1.7.1",
"eslint-plugin-babel": "^4.1.1",
"eslint-plugin-import": "^2.2.0",
"eslint-plugin-jsx-a11y": "^4.0.0",
const path = require("path");
const paths = require("./paths");
// paths.appSrc points to src folder
module.exports = {
context: paths.appSrc,
entry: {
vendor: [
"react",
"react-dom",
],
},
resolve: {
extensions: [".js", ".jsx"],
modules: [
paths.appSrc,
"node_modules"
],
alias: {
Components: path.resolve(paths.appSrc, "components/"),
}
}
};
{
"extends": "airbnb",
"parser": "babel-eslint",
"plugins": [
"react",
"jsx-a11y",
"import"
],
"settings": {
"import/resolver": {
"webpack": {
"config": "config/webpack.config.base.js"
}
}
}
}
import component1 from "Components/component1";
I was able to get rid of the ESLint errors by switching to babel-plugin-module-resolver. It's a good solution for project level imports until this issue get fixed.
{
"parser": "babel-eslint",
"env": {
"browser": true,
"node": false,
"jest": true
},
"extends": "airbnb",
"settings": {
"import/resolver": {
"babel-module": {}
}
}
}
{
"plugins" : [
"transform-runtime",
["module-resolver", {
"root": ["./src"]
}]
],
"presets" : [["es2015", { "modules": false }], "react", "stage-0"]
}
Using the webpack resolver and seeing this depending on configuration. An alias like @ works but an alias like @name doesn't. I'm just going to disable this rule for now as it is unreliable when working with Webpack.
You're using an alias that's otherwise a valid npm scope? o.O
eslint-import-resolver-webpack works very good with webpack 3: https://www.npmjs.com/package/eslint-import-resolver-webpack
I have need to add
"settings": {
"import/resolver": {
"webpack": {}
}
},
in my .eslintrc
@ljharb is that a constructive comment?
My point is simply that webpack supports this, while the import/resolver doesn't.
It's honestly fine with me if that's how it's going to work, but I'm assuming people will probably expect an alias that works with webpack to also just work with the webpack import/resolver.
I am asking because I'm genuinely surprised that anyone would ever attempt to make an alias like that. If you try a name that is not a valid npm name, does it work in both?
If so, that might be the way to fix this bug here.
https://github.com/benmosher/eslint-plugin-import/issues/496#issuecomment-282559042
@mudrz is your file on the filesystem foo or foo.js? if it's the latter, I'm surprised it doesn't work. if it's the former, I would believe that the resolver doesn't respect webpack 2's implicit no-extension resolution.
@benmosher it was foo.js, imported as foo
There's something in my setup that I haven't figured out yet. Right now webpack aliases work (both in webpack builds and eslint import plugin), but only if I use capital letter for the alias name. They are not recognized if they start with a special symbol like @ or lowercase letter.
Unfortunately I made lots of other random changes (out of desperation) including switching from airbnb to the default react-create-app eslint configuration (+prettier), so it could be that the dependencies are different versions or that the issue has already been resolved.
I could test something if it would be of help to you, please let me know
Any updates from anyone yet? Currently trying to setup linters at work.
In webpack.config:
extensions: ['', '.js', '.jsx', '.json'],
resolve: {
alias: {
Api: path.resolve(__dirname, 'src/api'),
Modules: path.resolve(__dirname, 'src/modules'),
// ...
In .eslintrc:
"settings": {
"import/resolver": {
"webpack": {
"config": "webpack.config.babel.js"
}
}
},
In some file.jsx which fails:
import SubApp from 'Modules/subapp/container';
// This is a jsx file that exists
But this works:
import SubApp from 'Modules/subapp/container.jsx';
// This is a jsx file that exists
For anyone looking at this, I was able to fix this issue by modifying how I export my config in webpack.config.js
In the config file I had something like
const config = {
// webpack configs
}
export default config
Changing it to using export.defaults worked.
const config = {
// webpack configs
}
export.defaults = config
Adding this to my eslint config worked in my case:
"settings": {
"import/resolver": {
"webpack": {
"config": "webpack.dev.js"
}
}
}
This issue was resolved for us by removing special symbols (@) in our aliases.
You have to add these 3 packages
1. babel-plugin-module-resolver
2. * eslint-plugin-import*
3. eslint-import-resolver-babel-module
and have to add the following code in eslintrc
"settings": {
"import/resolver": {
"babel-module": {}
}
}
Working fine for me..
Regarding @adamPaulMathew and the others answer, the issue is resolved on my local finally.
I did this:
// add these code to .eslintrc
"settings": {
"import/resolver": {
"webpack": {
"config": "webpack.dev.js"
}
}
}
And install these packages by run this code in your terminal
npm i --save-dev babel-plugin-module-resolver eslint-import-resolver-webpack eslint-plugin-import
Guys, I found another solution, better to say workaround.
Just take this 4 steps.
1) npm install --save-dev eslint-import-resolver-alias or yarn add --dev eslint-import-resolver-alias.
2) Create alias.js (it will take all directories under YOUR_PROJECT/src and use as modules).
/**
* Creates key-value map of local modules under 'src' directory.
*
* For example:
* `Action` is similar to `src/action`.
* `Reducer` is similar to `src/reducer`.
*
* Very usuful if you need to import local module, but don't want
* to be stuck with deep nested paths like `'./../../../../action';`
*/
const fs = require('fs');
const path = require('path');
const SRC_DIRECTORY = './src';
const localModules = fs
.readdirSync(SRC_DIRECTORY)
.filter(f => f.indexOf('.') === -1)
.reduce(
(modules, directory) =>
Object.assign({}, modules, {
[`${capitalizeFirstLetter(directory)}`]: path.resolve(__dirname, SRC_DIRECTORY, directory)
}),
{}
);
function capitalizeFirstLetter(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
module.exports = localModules;
3) Add extra lines to your webpack.config.js.
// Your aliases.
const localAliasModules = require('./alias');
module.exports = {
// Your webpack settings and ...
resolve: {
alias: localAliasModules
}
};
4) Add extra lines to your .eslintrc.js (file extension is necessary).
// Your alias modules.
const localAliasModules = require('./alias');
// Convert to appropriate format (key, value will be in array as first and second elements).
const resolvedAliasModules = Object.keys(localAliasModules).map(name => [name, localAliasModules[name]]);
module.exports = {
// Your eslintrc settings and ...
settings: {
'import/resolver': {
alias: resolvedAliasModules, // Your extra alias modules.
webpack: {} // Listen for webpack settings.
}
}
};
Btw. If you will place alias after webpack: {}, it will not work at all.
Looks like import/resolver is invoking each resolver in sequence.
Unfortunately I didn't find a way how to control the sequence (Array?), because Object is not best way to handle it.
is this a webpack bug? with _eslint-import-resolver-webpack_ appending @ to the alias makes it not work (also won't work with _eslint-import-resolver-babel-module_). appending special chars like $ works (with _eslint-import-resolver-babel-module_ it doesn't), and like others said not appending anything works too.
As initially stated a long time ago
not so much a bug as a missing feature.
I have not personally prioritized this because it means increasing the resolver API surface area, and I just haven't had sufficient time+motivation to do that in the intervening years. 馃槄 Is a substantial project to support this, AFAIK. Though the 82 馃憤's suggest it'd be a good feature for the community at large.
gonna prefix with _ since it works with both webpack (client) and babel-module (server) resolvers 馃崅
It also doesn鈥檛 respect the ordering rules. Our webpack aliases are considered external packages.
I tried with the $ and _ prefixes instead of @, as @galki recommended, but I didn鈥檛 manage to make it work.
eslint-plugin-import does pick up the correct webpack config, though, as confirmed by running:
DEBUG=eslint-plugin-import:* ./node_modules/.bin/eslint --fix .
I've run into this issue when using react-native-web.
When I use
import { View } from "react-native";
I get:
'react-native' should be listed in the project's dependencies. Run 'npm i -S react-native' to add it (import/no-extraneous-dependencies)
I use webpack and babel - I've set up
"react-native$": "react-native-web"
in webpack's aliases.
Considering the popularity of react-native-web It would be great if eslint-plugin-import supported that case.
@mieszko4 what's the $ for there? We have the same setup with no issues:
"react-native": "react-native-web"
@aaroncraig10e $ is used to mark the exact match (like in regex) so that react-native-something-else is not aliased.
Anyway, I figured out that $ is not the problem here - using your alias does not work for me.
What I figured out is that even using
"react-native": resolve(__dirname, "../node_modules/react-native-web")
does not work fo me. But if I copy react-native-web to some other folder and set it up as
"react-native$": resolve(__dirname, "../hmm/react-native-web")
it does work.
So it seems that whenever the plugin resolves to folder with node_modules it screams with an error...
I continued debugging it.
The alias pointing outside of node_modules worked for me because if it is external it does not report the error - which is fine:
https://github.com/benmosher/eslint-plugin-import/blob/8c9c3b86ac8bf22ca194caad51102335b088d28b/src/rules/no-extraneous-dependencies.js#L107
I have an idea how to fix it - Instead of using name we should use resolved and extract name from it:
https://github.com/benmosher/eslint-plugin-import/blob/8c9c3b86ac8bf22ca194caad51102335b088d28b/src/rules/no-extraneous-dependencies.js#L111-L114
For my case:
{ name: "react-native", resolved: '/home/mieszko4/myProject/node_modules/react-native-web/dist/index.js' }
So if we could just parse resolved to extract package name, i.e. in this case react-native-web that would solve the problem.
What do you think, am I missing something here?
This change works for me https://github.com/benmosher/eslint-plugin-import/pull/1119
But since I do not know any internals of the plugin I am sure there is a better way to rewrite that.
I webpack upgrade. I see to fix.
I tried literally everything in the post that led me here (https://github.com/Microsoft/vscode-eslint/issues/464) and this post. In the first post it said to try adding @babel/register to .eslintrc, so I converted my .eslintrc.json to .eslintrc.js. Then one by one I tried the rest. After all failed, I reverted .eslintrc.js to .eslintrc.json and thought, maybe I should try adding settings now, and this combination worked for me 馃帀
I already had eslint-plugin-import and babel-plugin-module-resolver installed, so I just installed npm install --save-dev eslint-import-resolver-babel-module
// ...
"settings": {
"import/resolver": {
"babel-module": {}
}
},
// ...
const path = require('path');
const APP_DIR = path.resolve(__dirname, 'admin/js/application');
const root = [path.resolve('./')];
const commonPlugins = [
[
require.resolve('babel-plugin-module-resolver'),
{
root,
alias: {
'app': APP_DIR,
'marionette': 'backbone.marionette',
'fileupload': 'blueimp-file-upload',
'Fuse': 'fuse.js',
'jquery-validate': 'jquery-validation',
'bootstrap-confirmation': 'bootstrap-confirmation2/dist/bootstrap-confirmation.js',
'test-helpers': path.resolve(__dirname, 'test-helpers'),
'libs': path.resolve(__dirname, 'admin/js/libs'),
}
},
]
];
module.exports = {
presets: [
['@babel/preset-env', {'modules': false} ]
],
plugins: [
'@babel/plugin-syntax-dynamic-import',
'@babel/plugin-proposal-object-rest-spread',
'@babel/plugin-proposal-class-properties',
...commonPlugins
],
env: {
'test': {
'presets': [
['env', { 'targets': { 'node': 'current' }}]
]
}
}
};
Replace eslint-import-resolver-webpack with eslint-import-resolver-alias
$ yarn add eslint-import-resolver-alias -D
My .eslintrc file:
Change
"settings": {
"import/resolver": {
"webpack": {
"config": "webpack.config.js"
}
}
},
to
"settings": {
"import/resolver": {
"alias": {
"map": [
["~", "./src"]
],
"extensions": [".mjs", ".js", ".vue"]
}
}
},
And here is my webpack.config.js:
resolve: {
extensions: ['.mjs', '.js', '.vue'],
alias: {
vue$: 'vue/dist/vue.esm.js',
'~': path.join(__dirname, 'src'),
},
},
Most helpful comment
Everywhere on Github, "+1" comments are not helpful nor necessary. Please indicate your support by adding a thumbs up reaction to the original post.
I will now delete the existing +1 comments, and any future ones. Thanks!