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

Document that package.json overrides are not used when a package is installed as a dependency. #975

Open
everett1992 opened this issue Feb 15, 2024 · 5 comments

Comments

@everett1992
Copy link

I'm pretty sure this explains the behavior I'm seeing, but I couldn't find it documented anywhere.

package.json overrides are only applied from the root package. If a dependency have overrides they are ignored, they aren't even applied to that package's subtree.

Here's an example

There's some package A that depends on lodash 3.

{
  "name": "a", "version": "1.0.0",
  "dependencies": { "lodash": "^3.10.1" }
}

Your package B depends on a, but overrides lodash to 4. You're confident that a actually works with 4, at least in your use case.

{
  "name": "b", "version": "1.0.0",
  "dependencies": { "a": "file:~/test/a/a-1.0.0.tgz" },
  "overrides": { "a": { "lodash": "^4" } }
}

You have some consumer C that uses your library.

{
  "name": "c", "version": "1.0.0",
  "dependencies": { "b": "file:~/test/b/b-1.0.0.tgz" }
}

C will still install lodash 3, ignoring overrides in B.

$ npm explain lodash
lodash@3.10.1
node_modules/lodash
  lodash@"^3.10.1" from a@1.0.0
  node_modules/a
    a@"file:~/axios-test/a/a-1.0.0.tgz" from b@1.0.0
    node_modules/b
      b@"file:~/axios-test/b/b-1.0.0.tgz" from the root project

I'm guessing this is by design? If so it should be documented. I'd also like to hear a short justification.
I checked these pages as well as searching for overrides

I maintain a package that depends on axios and aws4-axios, but aws4-axios has an incorrect peer dependency that I have to override. I realized that overrrides are not transitive when they fixed my package, but not a test consumer.
I naïvely expected the overrides to apply to the sub-tree of my package, as if C declared

"overrides": {
  "b": { ...b.overrides },
}
@ljharb
Copy link
Contributor

ljharb commented Feb 15, 2024

Yes, this is 1000% by design. Overrides are for apps, not packages.

@everett1992
Copy link
Author

everett1992 commented Feb 15, 2024

I can take a stab at updating docs tomorrow.

Should npm publish warn if a package has overrides?
What's the reason for overrides being app only?
I can kind of see a security story but I don't fully grasp it. Applying overrides to the subtree that declares them seems right

@ljharb
Copy link
Contributor

ljharb commented Feb 15, 2024

Any time an npm feature affects published packages it can infect the ecosystem very rapidly - even if there's an argument to be made that it should work that way, the risk of doing it wrong vastly outweighs the harm of doing nothing.

In this case, it's simply not your place to override anything in a dependency, unless you're the end user (who can do anything they like). If package A wants to claim it only supports lodash 3, then that means that every single transitive end user of package A either is forced to stick to lodash 3, or, override to lodash 4. The solution for you to wrap that into a package is to fork it, not to override it.

@everett1992
Copy link
Author

In this case, it's simply not your place to override anything in a dependency, unless you're the end user

But in a sense my library is the end user. Npm and node_modules support hiding dependencies. B could override it's A>lodash edge without affecting other lodash or A>lodash edges.

@ljharb
Copy link
Contributor

ljharb commented Feb 15, 2024

No library is an end user :-) only an application is.

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

No branches or pull requests

2 participants