eslint-plugin-import: no-extraneous-dependencies doesn't support nested package.json
Example of my project structure:
├── package.json
├── src
│ ├── components
│ │ ├── Avatar
│ │ │ ├── Avatar.css
│ │ │ ├── Avatar.js
│ │ │ ├── README.md
│ │ │ └── package.json
│ │ ├── Button
│ │ │ ├── Button.css
│ │ │ ├── Button.js
│ │ │ ├── ButtonSpinner.css
│ │ │ ├── ButtonSpinner.js
│ │ │ ├── README.md
│ │ │ └── package.json
Root package.json
contains all dependencies, nested package.json
looks like this:
{
"name": "Avatar",
"main": "Avatar.js"
}
That’s why I got wrong warnings:
src/components/Avatar/Avatar.js
1:1 error 'react' should be listed in the project's dependencies. Run 'npm i -S react' to add it import/no-extraneous-dependencies
2:1 error 'classnames' should be listed in the project's dependencies. Run 'npm i -S classnames' to add it import/no-extraneous-dependencies
Is this fixable?
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 41
- Comments: 51 (13 by maintainers)
Commits related to this issue
- chore(pack): Disable no-extraneous-dependencies This rule doesn't work with nested package.json files: https://github.com/benmosher/eslint-plugin-import/issues/458 — committed to lgeiger/nteract by lgeiger 8 years ago
- chore(pack): Disable no-extraneous-dependencies This rule doesn't work with nested package.json files: https://github.com/benmosher/eslint-plugin-import/issues/458 — committed to lgeiger/nteract by lgeiger 8 years ago
- Add support for nested package.json. Fix #458 — committed to ramasilveyra/eslint-plugin-import by ramasilveyra 8 years ago
- Add support for nested package.json. Fix #458 — committed to ramasilveyra/eslint-plugin-import by ramasilveyra 8 years ago
- Add support for nested package.json. Fix #458 — committed to ramasilveyra/eslint-plugin-import by ramasilveyra 8 years ago
- Add support for nested package.json. Fix #458 — committed to ramasilveyra/eslint-plugin-import by ramasilveyra 8 years ago
- Add support for nested package.json. Fix #458 — committed to ramasilveyra/eslint-plugin-import by ramasilveyra 8 years ago
- Add support for nested package.json. Fix #458 — committed to ramasilveyra/eslint-plugin-import by ramasilveyra 8 years ago
- Add support for nested package.json. Fix #458 — committed to ramasilveyra/eslint-plugin-import by ramasilveyra 8 years ago
When trying to pass a function to the rule with both eslint 5.16.0 and 6.0.0-alpha I get
This would be great for me. I work on a monorepo (here’s why) with a root package.json and sub-directories with their own package.json. As it stands, I just have to disable this rule, which is a bummer, because it’s so useful.
As I understand it, in order to resolve the installed dependencies accurately (in a way that matches node’s module system), the
getDependencies
function would basically need to recurse up all found package.json files, updating the context arg as it goes, until the app root directory, then merge the dependencies object from eachpackage.json
(something likeObject.assign({}, ..._.pick(packageContents, 'dependencies'))
, wherepackageContents
is an array of the contents from root to leaf).I understand the concerns about introducing this, but I would still like to put a strong favorable vote towards adding this as an option. Monorepos are fairly common and probably worth supporting. See Lerna for evidence of this, which can also serve as a way to make a quick example repo test case.
And in terms of the more general question of sub-packages not declaring all their dependencies and therefore having to do multiple
npm install
s in your codebase, I think that’s just part of the tradeoff one makes. Part of the benefit of Lerna is having a CLI that makes it easy to do monorepo npm stuff.Expanding on my previous comment, here’s what my ESLint settings look like:
Inside
src
I have 3 main folders:services
,components
, andscenes
(this is for a large React Native app, by the way). Each of those main folders contains apackage.json
that looks like this (each with their respective names):Elsewhere in my project I can now import a component (or a service or a scene) by simply typing:
This is much more manageable than typing something like:
Currently, I get
import/no-extraneous-dependencies: 'react' should be listed in the project's dependencies. Run 'npm i -S react' to add it
because the minimalpackage.json
doesn’t have dependencies and the rule doesn’t care to look up higher in the directory tree.If the rule allowed me to do the following, it would solve this issue:
I just hit this today too. I think the only real way to fix is to enable an array of
packageDirs
to use, something like…Here’s a version that works in all contexts (lerna root + packages / vscode) with a root level
.eslintrc.js
config :The
context.getFilename()
gets you the nearestpackage.json
(it’s the same code that’s used inside the rule source), and the__dirname
gets you the rootpackage.json
edit: doesn’t cover sibling package dependencies though, since the require are declared using the fqpn
@scope/package
, for this to work the rule would need to accept package name exceptionsLooks like #685 was merged in May.
In my case, I was able to solve the problem with:
"import/no-extraneous-dependencies": ["error", {"packageDir": "./"}],
(.eslintrc.js & package.json are in the working directory root)Leaving this here because this is the page google led me to, but I would recommend checking out the docs for this rule.
When will this be merged?
@rjhilgefort this solved it for me:
Is there any news on @jacobrask issue? I guess many are experiencing this.
@kopax @kilpatty this is the code I currently use in my boilerplate:
'import/no-extraneous-dependencies': ['error', {'devDependencies': true, 'packageDir': path.join(__dirname, './')}],
That being said, I haven’t worked on a project that uses multiple package.json files in a long time, so your mileage may vary
Jumping here, monorepo user, maybe we could:
Or just a way to express some different packages.json to read. Dunno
Just throwing a +1 for the solution that @tizmagik proposed. I’m hitting this problem in a monorepo architecture as well. I see that this issue is closed, should I created a new issue for this?
Hello!
If you want you can try my fix with
npm i -D ramasilveyra/eslint-plugin-import#fix-root-pkg-copy-dont-remove
(https://github.com/ramasilveyra/eslint-plugin-import/tree/fix-root-pkg-copy-dont-remove, fork it and rebuild if you want 😃 ) until #685 gets a review & merge. So far It works well on the projects where I had this problem.Example of conf:
so we are on 2020 no further improvements on this apart just to switch the rule off?
You don’t; eslint provides it.
Yup, an option to check all package.json for dependencies would work for me.
Also wondering if this has a solution other than “off”
Agreed that it’s more of a Node.js issue. And sure, being able to configure this rule to support nested package.json would be a good thing! I’m just saying that having this feature enabled by default could lead to some hard to find bugs for people that are not aware that the situation I explained above can happen.
In some specific situations, enabling this rule to go up the hierarchy of
package.json
will make it less powerful by introducting some unexpected behaviour.Let’s say you have the following project structure:
with the following contents:
Then we have the following outputs:
Even though we declared the dependency on
lodash
3.10.1 only once in the rootpackage.json
, it’s not actually this version that is imported innested/file2.js
. It happens becausebabel-types
depends onlodash
^4.2.0 and with the npm flat module structure, this new version of lodash ends up directly innested/node_modules/lodash
and “shadows” the version oflodash
required by our rootpackage.json
.However, if
nested/package.json
also declared an explicit dependency onlodash
3.10.1 then it will be this version that npm would write innested/node_modules/lodash
. Indeed, thelodash
package required bybabel-types
would be undernested/node_modules/babel-types/node_modules/lodash
and all would be fine.Thus, the only sane situations in which it would be good to support nested
package.json
is when the deep ones doen’t have any dependencies (dev included). Because then,nested/node_modules
won’t exist andlodash
3.10.1 will get picked up by the Node.js module resolution algorithm.In the end, the use-cases of @nkt and @migueloller will work fine, but it’s not generally safe - at least version wise - to support nested
package.json
.