-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
no-extraneous-dependencies: aliases are not considered "project"-level imports #496
Comments
Ah, yeah, not so much a bug as a missing feature. 😅 It's tough to disambiguate "project" dependencies from |
Is this the same issue with |
@simonbuchan I suspect that's true. Though I wouldn't be surprised if certain (if not all) |
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 |
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 |
Another thing to keep in mind when using eslint-import-resolver-webpack:
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) folder structure
package.json "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", webpack.config.base.jsmodule.exports = {
stats: { modules: false },
resolve: {
extensions: ['.js', '.jsx'],
alias: {
'foo': path.resolve(__dirname, `/someFolder/foo`),
},
},
} eslintrc.jsmodule.exports={
extends: ['airbnb'],
parser: 'babel-eslint',
settings: {
'import/resolver': {
'webpack': {
'config': 'webpack.config.base.js'
}
}
},
} usageimport Something from 'foo' ESLint Errors:import/no-extraneous-dependencies |
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! |
|
Just fyi it might be an issue with webpack after all: |
The following configuration works for me. Folder Structure:
package.json "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", webpack.config.base.jsconst 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/"),
}
}
}; .eslintrc.json{
"extends": "airbnb",
"parser": "babel-eslint",
"plugins": [
"react",
"jsx-a11y",
"import"
],
"settings": {
"import/resolver": {
"webpack": {
"config": "config/webpack.config.base.js"
}
}
}
} container1.jsximport component1 from "Components/component1"; |
I was able to get rid of the ESLint errors by switching to .eslintrc
.babelrc
|
Using the webpack resolver and seeing this depending on configuration. An alias like |
You're using an alias that's otherwise a valid npm scope? o.O |
I have need to add
in my |
@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. |
#496 (comment) |
@benmosher it was 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 |
This change works for me #1119 |
I webpack upgrade. I see to fix. |
I tried literally everything in the post that led me here (microsoft/vscode-eslint#464) and this post. In the first post it said to try adding I already had .eslintrc.json
.babelrc.js
|
Replace $ yarn add eslint-import-resolver-alias -D My Change "settings": {
"import/resolver": {
"webpack": {
"config": "webpack.config.js"
}
}
}, to "settings": {
"import/resolver": {
"alias": {
"map": [
["~", "./src"]
],
"extensions": [".mjs", ".js", ".vue"]
}
}
}, And here is my resolve: {
extensions: ['.mjs', '.js', '.vue'],
alias: {
vue$: 'vue/dist/vue.esm.js',
'~': path.join(__dirname, 'src'),
},
}, |
@Shyam-Chen’s solution initially worked for me, but the issue presents again when upgrading to version 2.25.4 or higher. |
@HughxDev i'd love to get a reproducible test case so i can fix that, if so. |
Doing this then started throwing e.g.
for all my node stuff ... |
Actually, that just broke a bunch of other stuff. Yikes! |
That's still the correct thing to do, though - the node resolver should basically always be last. |
No, it's not correct. |
@cha0s can you explain why you think it's not correct? |
Sure! (one of) My webpack target(s) is node. Therefore, I need webpack resolution as well as node resolution. This utility seems to only offer an either-or approach despite appearing to support multiple resolvers. |
right - so your resolvers object should have two keys: webpack, and then node. If that ignores the node resolver it'd only be if the webpack resolver is resolving the path first. |
Yup. The rest of the config is filled out dynamically. This is what the final config looks like: {
"extends": [
"/absolute/path/to/flecks/node_modules/eslint-config-airbnb/index.js",
"/absolute/path/to/flecks/node_modules/eslint-config-airbnb/hooks.js"
],
"globals": {
// Not going to paste this ...
},
"ignorePatterns": [
"dist/**",
"build/flecks.hooks.js",
"test/lint/fail.js"
],
"overrides": [
{
"files": [
"build/**/*.js"
],
"rules": {
"import/no-extraneous-dependencies": [
"error",
{
"devDependencies": true
}
],
"import/no-dynamic-require": "off",
"global-require": "off"
}
},
{
"files": [
"test/**/*.js"
],
"rules": {
"prefer-arrow-callback": [
"error",
{
"allowNamedFunctions": true
}
],
"brace-style": "off",
"class-methods-use-this": "off",
"import/no-extraneous-dependencies": "off",
"import/no-unresolved": "off",
"max-classes-per-file": "off",
"no-new": "off",
"no-unused-expressions": "off",
"padded-blocks": "off"
}
}
],
"parser": "/absolute/path/to/flecks/node_modules/@babel/eslint-parser/lib/index.cjs",
"parserOptions": {
"requireConfigFile": false,
"babelOptions": {
"configFile": "/absolute/path/to/flecks/node_modules/@flecks/build/build/babel.config.js"
}
},
"plugins": [
"@babel"
],
"rules": {
"brace-style": [
"error",
"stroustrup"
],
"import/no-import-module-exports": "off",
"import/prefer-default-export": "off",
"jsx-a11y/control-has-associated-label": [
"error",
{
"assert": "either"
}
],
"jsx-a11y/label-has-associated-control": [
"error",
{
"assert": "either"
}
],
"no-param-reassign": [
"error",
{
"props": false
}
],
"no-plusplus": "off",
"no-shadow": "off",
"object-curly-spacing": "off",
"padded-blocks": [
"error",
{
"classes": "always"
}
],
"yoda": "off"
},
"settings": {
"import/resolver": {
"webpack": {
"config": {
"resolve": {
"alias": {
"@flecks/db": "/absolute/path/to/flecks/packages/db/src",
"@flecks/web": "/absolute/path/to/flecks/packages/web/src",
"@flecks/socket": "/absolute/path/to/flecks/packages/socket/src",
"@flecks/session": "/absolute/path/to/flecks/packages/session/src",
"@flecks/server": "/absolute/path/to/flecks/packages/server/src",
"@flecks/repl": "/absolute/path/to/flecks/packages/repl/src",
"@flecks/redux": "/absolute/path/to/flecks/packages/redux/src",
"@flecks/redis": "/absolute/path/to/flecks/packages/redis/src",
"@flecks/react-redux": "/absolute/path/to/flecks/packages/react-redux/src",
"@flecks/react": "/absolute/path/to/flecks/packages/react/src",
"@flecks/passport-react": "/absolute/path/to/flecks/packages/passport-react/src",
"@flecks/passport-local-react": "/absolute/path/to/flecks/packages/passport-local-react/src",
"@flecks/passport-local": "/absolute/path/to/flecks/packages/passport-local/src",
"@flecks/passport": "/absolute/path/to/flecks/packages/passport/src",
"@flecks/headless": "/absolute/path/to/flecks/packages/headless/src",
"@flecks/fleck": "/absolute/path/to/flecks/packages/fleck/src",
"@flecks/electron": "/absolute/path/to/flecks/packages/electron/src",
"@flecks/dox": "/absolute/path/to/flecks/packages/dox/src",
"@flecks/docker": "/absolute/path/to/flecks/packages/docker/src",
"@flecks/create-fleck": "/absolute/path/to/flecks/packages/create-fleck/src",
"@flecks/create-app": "/absolute/path/to/flecks/packages/create-app/src",
"@flecks/core": "/absolute/path/to/flecks/packages/core/src",
"@flecks/build": "/absolute/path/to/flecks/packages/build/src",
"/absolute/path/to/flecks/packages/db/node_modules/webpack": "/absolute/path/to/flecks/packages/db/node_modules/webpack"
},
"extensions": [
".mjs",
".js",
".json",
".wasm"
],
"fallback": {
"@flecks/db": "/absolute/path/to/flecks/packages/db",
"@flecks/web": "/absolute/path/to/flecks/packages/web",
"@flecks/socket": "/absolute/path/to/flecks/packages/socket",
"@flecks/session": "/absolute/path/to/flecks/packages/session",
"@flecks/server": "/absolute/path/to/flecks/packages/server",
"@flecks/repl": "/absolute/path/to/flecks/packages/repl",
"@flecks/redux": "/absolute/path/to/flecks/packages/redux",
"@flecks/redis": "/absolute/path/to/flecks/packages/redis",
"@flecks/react-redux": "/absolute/path/to/flecks/packages/react-redux",
"@flecks/react": "/absolute/path/to/flecks/packages/react",
"@flecks/passport-react": "/absolute/path/to/flecks/packages/passport-react",
"@flecks/passport-local-react": "/absolute/path/to/flecks/packages/passport-local-react",
"@flecks/passport-local": "/absolute/path/to/flecks/packages/passport-local",
"@flecks/passport": "/absolute/path/to/flecks/packages/passport",
"@flecks/headless": "/absolute/path/to/flecks/packages/headless",
"@flecks/fleck": "/absolute/path/to/flecks/packages/fleck",
"@flecks/electron": "/absolute/path/to/flecks/packages/electron",
"@flecks/dox": "/absolute/path/to/flecks/packages/dox",
"@flecks/docker": "/absolute/path/to/flecks/packages/docker",
"@flecks/create-fleck": "/absolute/path/to/flecks/packages/create-fleck",
"@flecks/create-app": "/absolute/path/to/flecks/packages/create-app",
"@flecks/core": "/absolute/path/to/flecks/packages/core",
"@flecks/build": "/absolute/path/to/flecks/packages/build"
},
"modules": [
"node_modules"
],
"symlinks": false
}
}
},
"node": {}
},
"react": {
"version": "18.2.0"
}
}
} Fails on the socket package if line linked is removed. If you're interested in reproducing locally, I'll write out the few commands you have to run against that project to do so. |
That package doesn't define a "main" or an "exports" (not that we support "exports" yet), and it doesn't have an index.js https://github.com/cha0s/flecks/tree/master/packages/socket I do see that the build process is supposed to produce an |
It has a I don't understand your question. Are you asking me if lint is run against the build artifact? The answer to that question would be no. Lint is run against the source code. May I ask why that's relevant? It may be useful to others to know if lint will break if they structure their files a certain way. |
Right - so, without a build artifact, that package doesn’t have a “main” and is thus unresolvable. Obviously you wouldn’t lint built code - but unlike most eslint plugins, this one runs across files. So when linting a file that imports that package, that package’s build output must exist or else you’ll get failures. |
I found that removing the
That's an interesting aside, but the error is not a result of importing the socket package. I linked the source of the error, it's the The examples I've provided are open source: CI and all. If you're interested in reproducing the bug locally to develop a fix, I will help if you need assistance building the project. |
Interesting. I'd prefer a much smaller repro, tbh.
that's why i looked at the socket package. the |
Hi, not sure if it is a bug. If no sorry.
I use a Webpack resolve condition:
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.
The text was updated successfully, but these errors were encountered: