Replies: 4 comments 1 reply
-
Hi, thank you for this post - many interesting points have been raised! Let's start!
First of all, the priority for The dependency graph declared by a set of Hoisting crosses boundaries between packages and allows non-strict accesses during runtime. The symlinks break compatibility with existing npm packages. Can we not use symlinks and not hoist and be strict with nm linker? Well, unfortunately when we are not using hoisting the number of duplicate packages in the tree starts to grow very fast, killing installation performance and occupying disk space. We can solve the problem with the disk space growth by using hardlinks, because duplicated files are the same, but we will still have a growing performance penalty because each hardlink creation takes time. Because of the above, strict installs with nm linker in the sense of pnpm-strictness are not possible. Note, that
If you will not use hoisting, you will end up creating millions of hardlinks to content-addressable store in order for your install to be strict. Or you must use symlinks as
It will have better strictness than nm linker, worse compatibility with existing npm packages and worse strictness than pnp. Its somewhere in the middle by all these metrics.
AFAIK, with
It is all about trade-offs - if you want to consume any npm package in your project and want your project to be strict, use
Right. Current
The problem with this option is that the number of files that need to be written is doubled compared to
Because you might not always want to deal with global store risks when you modify a file inside node_modules of one project and changes are reflected in another project. You can remove
Yes, it sounds like |
Beta Was this translation helpful? Give feedback.
-
Another interesting thing is that while pnpm-style installs are a bit stricter than typical nm, they aren't enough. For example, if you add Another interesting thing is that node_modules-style installs, even the pnpm one, can't support some edge cases in peer dependency resolution, essentially ignoring intra-workspaces peer dependencies. Those cases don't happen often since you tend to keep the same dependencies in all your workspaces, but once you start to diverge the debugging can be quite annoying ... So to answer your post: PnP is the only design that can provide perfect semantics & enforced boundaries. The node_modules design has fundamental flaws that even smart implementations like the pnpm strategy can't workaround and that make a "node_modules strict mode" impossible. In the end the pnpm benefits are:
On the other hand:
|
Beta Was this translation helpful? Give feedback.
-
Thanks a lot for such quick and detailed responses! So much interesting information in there! It seems I've been mixing a few things together indeed and somehow assumed that I totally missed that Another thing I missed is that creating hardlinks comes at a performance cost and knowing this, the difference between Many arguments in favor of using PnP that I wasn't aware of were mentioned in your posts. Ultimately, it seems that to have packages in a complete order and profit from the best possible performance (or even zero-installs) at the same time, PnP is the way to go and may be what I'm looking for. It would be great to have a page in the docs explaining all of this (differences between linkers with regards to hardlinks, symlinks, performance, strictness, correctness of the installs, compatibility, etc., and to see how PnP can solve all of these issues). I think there are many others that don't understand all of these concepts in detail and don't know all the advantages of PnP. From the docs, I also wasn't sure what all the possible values of Maybe all of the options can be nicely summarized as well:
But I'm failing to include
These are indeed some things that many of us, Yarn users, may not be aware of. Finally, I'm highlighting a few of the very interesting things that were mostly new to me: Symlinks:
Hardlinks:
Strictness:
Compatibility:
Whoa 🙀:
|
Beta Was this translation helpful? Give feedback.
-
Seeing #3338 merged, I have one more question. In your answers you cleared it up to me that pnpm-style linker reduces compatibility due to the usage of symlinks. My question is – how significant this is? Do I run into this when building a simple React app or a Node.js-powered backend or does it occur only in some edge cases? What are some examples of popular but incompatible libraries? Thanks! |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi, first of all, big thanks to the Yarn team for all the great work and congrats on the awesome Yarn v3 release!
This may be in part a question, in part a clarification of some functionality, and in part maybe also a feature suggestion.
Strict installs with
node-modules
?We've seen different approaches to module installs and linking in the npm/yarn/pnpm ecosystems and looking at Yarn as the pioneer of strictness and pnp, I have a question:
Is currently it possible to use
nodeLinker: node-modules
and achieve strict installs?By "strict installs" I mean the same module resolution behavior as pnp would provide and probably a similar one as pnpm does ("a non-flat node_modules, so code has no access to arbitrary packages"), although I know it's a bit more complicated and depends on hoisting settings, but what I mean is the strict settings.
Why?
I think having strict installs with
node-modules
linker may be a very good step on the road to pnp (and the perfect option for mixed pnp/node-modules setups).Moreover, it all seems to be related – strictness, linking, hoisting, and install speeds.
For instance, if content-addressable store is used, there may be no need for hoisting and all the related complexity, and that, in turn, will provide stricter installs and better speeds (skipping hoisting computations and using hardlinks).
Will pnpm-style linker solve it?
I know the release notes mention that the pnpm-style linker is planned so my next question is – will it provide strictness with node-modules?
(If I'm not mistaken, neither
nmHoistingLimits: workspaces
nornmHoistingLimits: dependencies
achieve that in full, although I'm not fully sure based on what the docs of these options mention.)What about
nmHoistingLimits
and hoisting in general?It seems like
nmHoistingLimits
bring some more strictness but I'm not fully sure from the rather brief docs for this feature what exactly will be the effect of these.It seems like with
nmHoistingLimits: dependencies
we may be getting similar strictness as we can get with pnpm without hoisting but I'm not fully sure about it in didn't try it out in depth.My question here is what are the practical impacts of
nmHoistingLimits: dependencies
:I've noticed that using
nmHoistingLimits: dependencies
makes linking about twice as slow on a project with multiple workspaces, but I guess it may also relate to hardlinks usage and that could be my next question...Using
nmMode: hardlinks-local
vs.nmMode: hardlinks-global
From the docs it seems to me that
hardlinks-local
uses hardlinks only for exact same packages in exact same version (that's interesting to me as there are no folder hardlinks so this still has to be done file-per file, right?) andhardlinks-global
links per-file and globally on a machine, not within a project (where is that cache stored?).I'm kind of missing a third option that sounds the most natural to me – linking per file within a project (like pointing all the hardlinks somewhere into
.yarn
, for instance), which is probably similar to usingnmMode: hardlinks-global
and pointing the global cache to local.yarn
(if that's even possible).I'm actually not sure why two different linkers need to exist here – could the local linker be just a global linker pointing to local
.yarn
directory? Or what are the actual differences?But maybe I simply misunderstood the docs about how these two options work. Maybe @larixer would correct me?
(From a quick try using these linkers doesn't seem to solve the slower speeds when used with
nmHoistingLimits: dependencies
.)Wrapping it up
It seems to me that there are many possible configurations using different combinations of
nmMode
andnmHoistingLimits
but just from the docs I'm not sure if I understand those correctly.Ultimately, when using pnp is not possible, I think the ideal setup for me would be to have fully strict
node-modules
linking with content-addressable store and no hoisting at all (and also no hoisting-related complexity and issues).Will the pnpm-style linker @arcanis is working allow for such installs? Or am I misunderstanding some of the current abilities of Yarn v3 and it's already possible (or never will be)?
Thanks for any replies and clarifications and sorry for such a long post!
Beta Was this translation helpful? Give feedback.
All reactions