-
Notifications
You must be signed in to change notification settings - Fork 488
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
Type helpers loose class-validator/class-transformer metadata in Yarn PnP environments #2169
Comments
Not sure if I'm following.
This sounds odd. Why outer package is obligated to list the inner's package peer/optional dependencies? cc @jmcdo29 in case you're familiar with PnP |
You're right. Instead of dependency. Updated the issue. |
Why should we flag it as a peer dependency if it is a dependency? |
On the one hand yes, but it the same it's weird when a package depends on another package, but neither satisfies its requirements nor asks a parent package to do that. Debugging such things is a nightmare.
Or alternatively we can say
From my POV one of the differences between dependencies and peer dependencies Is that a peer dependency must be a singleton whereas a dependency can exist in multiple instances and that's ok. BTW a package can be specified as dependency and peer dependency at the same time. I don't have a clear answer right now. For me |
I share your POV
IMHO It doesn't make sense.
So my POV here is that the package manager should automatically detect that inner dependency has peer dependencies and instruct the end-user (developer building an application) to install them. |
It makes sense when you need a peer dependency with a default version. Hypothetical
Well, I can only refer to @arcanis: yarnpkg/berry#3 (comment) |
You don't need to flag a dependency as a peer dependency for this. As long as versions match, NPM will dedupe your node_modules (I think Yarn v1 does that too as long as version ranges match) and make sure you only use 1 instance of webpack in your project, even if it's flagged as a "dependency" (not a peer dependency). If you need more flexibility and want your dependency to always behave as an actual peer dependency, you should flag it as a peer dependency and remove it from the dependencies.
I think this is a slightly different discussion. Let's say there's a package A that depends on package B that has a peer dependency on package C. Now, it turns out that package A needs and uses C (deeper dependency of B) as well (and previously - in older versions of Yarn/or when using NPM) it'd have been fine as C would have been implicitly installed anyway (inherited from package B). Yarn 2 PnP would require you to explicitly specify that C is also a peer dependency of A in this case - and I agree with this. However, what we're discussing here is a scenario in which package A depends on package B which has a peer dependency on package C, and package A never directly uses package C (there's no interaction between those two) - a subtle but vital difference. Hence, I don't see a reason why package A would have to list it as its peer dependency |
Seems not, the discussion is about a case when A depends on B that has a peer dependency C, but A doesn't directly uses C. A doesn't implicitly inherit transitive peer dependencies.
off topic
It literally sounds "it doesn't make sense, because a package manager may dedupe". But package managers are not smart enough to automatically guess which dependencies can be safely automatically deduplicated across different minor versions. I wouldn't expect that A@1.12.0 and A@1.0.5 will be implicitly deduplicated to 1.12.0 until I ask the package manager about that. still have "vietnamese flashbacks" about "smart" old npm versions that did many things implicitly. Seems like @arcanis thinks the same:
I agree, it's possible to specify wide range
IMO If you can get benefits from both approaches it's not a bad deal. Yarn and pNPM both support default peer dependencies. |
I wrote an article about this a couple of years ago: Implicit Transitive Peer Dependencies The gist is that while this kind of thing is easy to do when accepting the risk of "ghost dependencies", it turns out it's very (very) difficult to support while validating dependency accesses. There's a cyclic dependency in the graph generation that I didn't find a good way to solve - and I looked into it a couple times. I admit it's a little impractical, but our research showed that it usually wasn't a significant problem (the workaround was simple enough), and it's compatible with other package managers (in that they won't suddenly crash if you list the peer deps), so we decided to keep it as a limitation. There's also a little advantage of proceeding like this: the outer package is in full control of the environment under which the inner package runs. If it doesn't want the inner package to see a peer dependency (for example because it'd be slower, or would crash, or ...) they can "shortcut" the peer dependency chain by just intentionally omitting to forward the peer dependency. It's a bit fringe, of course. |
Thanks for chiming in & clarifying @arcanis, and for a thorough discussion @khmm12. Appreciate your time! Since it doesn't hurt to explicitly add the inner package's peer dependencies, let's just add them in to be compatible with Yarn PnP. Would you like to create a PR @khmm12? Let me know if you're busy and if so I'll take care of this myself! |
@kamilmysliwiec I'll create PRs for @nestjs/swagger and @nestjs/graphql 👍 |
Yarn PnP doesn't implicitly inherit transitive peer dependencies class-validator and class-transformer from @nestjs/mapped-types. Fixes nestjs#2169.
Yarn PnP doesn't implicitly inherit transitive peer dependencies class-validator and class-transformer from @nestjs/mapped-types. nestjs/swagger#2169
Just saw this one and was wondering if there is already an ETA when the PRs will be shipped. 👀 |
Is there an existing issue for this?
Current behavior
@nestjs/swagger
uses@nestjs/mapped-types
which usesclass-validator
andclass-transformer
(if they're present) to inherit validation/transformer metadata.@nestjs/swagger
brings@nestjs/mapped-types
as dependency.@nestjs/mapped-types
requiresclass-validator
andclass-transformer
as optional peer dependencies.@nestjs/swagger
doesn't provideclass-validator
andclass-transformer
.@nestjs/swagger
->@nestjs/mapped-types
checks whetherclass-validator
andclass-transformer
are present, sees that they aren't and doesn't inherit metadata (ref).Yarn PnP doesn't allow implicit requirements which may cause undefined behaviour. It means Yarn PnP expects from
@nestjs/swagger
to satisfy@nestjs/mapped-types
peer/optional dependencies since it's the direct dependency.Minimum reproduction code
https://gist.github.com/khmm12/c2a4bdab7dfa82d33f06c45a768ad6d7
Steps to reproduce
No response
Expected behavior
I see 2 possible solutions:
@nestjs/swagger
should specify@nestjs/mapped-types
as peer dependency instead of dependency.@nestjs/swagger
should specifyclass-validator
andclass-transformer
as optional dependencies.Package version
6.13
NestJS version
No response
Node.js version
No response
In which operating systems have you tested?
Other
No response
The text was updated successfully, but these errors were encountered: