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
Use consistent versions on new dependencies #5610
Comments
This might be a duplicate of #4686 |
I think it is at least closely related, although that pr seems to argue that the new dependency can sometimes use the old version, whereas I'm saying that the new dependency should sometimes force (perhaps with a warning/user prompt) an upgrade of the existing dependency. In my example, using |
Ah yes, good point. I think this is one of those things where no matter which way you implement it, 50% of the community will want it to work the other way and re-open it as an issue. I'll add the needs-discussion tag to this... @yarnpkg/core thoughts? |
Relying on dependencies being hoisted a certain way isn't safe. The only per-spec way of ensuring that the exact same version will be used across your app is to use peer dependencies (so for example as a real case, |
Can't you also use the resolutions field to be sure something is resolved as expected? |
The resolution field is also unsafe in this aspect since hoisting is an optimization, not a guarantee. Yarn would be allowed not to hoist them, leading to duplicate instances in memory. |
@arcanis There are thousands (if not millions) of packages that rely on some amount of hoisting out in the wild now. I believe that ship has sailed. @rally25rs I agree that there are two potentially reasonable courses of action here. I would suggest a confirmation prompt as a reasonable compromise (you could also gather metrics about which option people choose). The current approach is getting to be very problematic though. |
This question was raised is some form a few times, I agree with the idea that Yarn should give control over resolution tree considering hoisting. I don't think that @ForbesLindesay's proposal should be the default behavior though. Resolution logic implementation is a bit hard to read through, it is a recursive call but I would help review a PR :) |
This issue is raised every once in a while, but it's never been that big of an issue that we have to act now or everything is broken. This ship will sail if we start making promises, though, and that's something I'd like to avoid. Another issue is that perfect hoisting is a NP hard problem, so any implementation has to have some boundaries and heuristics to tweak it. Those used by npm and Yarn aren't the same (nor are they the same between versions, for what it's worth), and it is very likely we'll want to change them in the future in impredictable ways. The distinction between |
That being said, the behavior detailed in the original post (reusing existing resolutions) could be an nice optimization, not arguing against that. Just saying that it should not be needed for your packages to work. |
One issue I could imagine happening is that if we give people options as to how they want yarn to do resolutions and hoisting, then we're going to get a swarm of issues that are "package X wont install correctly" to which the answer will be "you have to use the I'm typically against package managers trying to work magic and fix everyone else's packages and would rather see the burden put on package managers to do things correctly (which is unlikely to happen in all cases, but I can dream...) This may be related to another use case that comes up constantly, and that is people transitioning to yarn from bower (since they kindly redirected people to use yarn). People quickly discover that yarn isn't a 1-to-1 match for the way bower ensured a "flattened" de-duped set of deps and want to know how to "flatten my web dependencies but not my nodejs devDependencies". I think the ability to have flattened dependencies here might fix the original issue because it would ensure there was only a single version of React. I have long been thinking of adding a feature to pass a manifest name to yarn (instead of always defaulting to package.json) so that you could do something like install package.json devDeps to node_modules/, then install web-package.json with --flat to web_modules/ However that too would cause problems because web packages have install scripts that run in node.js which assumes node_modules directories, so installing most packages to anything other than node_modules will cause errors. Maybe a potential feature would be to add another package.json section akin to |
My suggestion here is not that we make any changes to how hoisting happens in the case where there is no lock file. What I want to change is only what happens to the lock file when you add a dependency.
It wouldn't for me. I would not be willing to accept a fully flattened tree if there are genuinely incompatible versions of sub-dependencies. I need the dependencies to merge when the versions are compatible only.
Yuck, please don't do this.
Maybe. This could apply to
The promises made currently are "good enough" that people rely on them. If we could add something to "break" packages that use dependencies when they should use peer dependencies, maybe we could force people to move over. There is another scenario that is not currently handled well though: Package A depends on Package B and consumers of Package A may or may not use Package B. If the consumers use Package B, they must use the same version. Peer dependencies are not well suited, because it forces everyone to list B as a dependency, even if they only need it because they are using A. Dependencies are wrong because even if the versions are compatible, you could end up with two versions of B. |
Do you want to request a feature or report a bug?
I feel it's a bug, but it's all a matter of perspective I suppose.
What is the current behavior?
If the current behavior is a bug, please provide the steps to reproduce.
yarn add dependency-a
{"sub-dependency": "^1.0.1"}
yarn add dependency-b
These steps result in dependency-a depending on sub-dependency 1.0.0 and dependency-b depending on sub-dependency 1.0.1, even though both are capable of picking up sub-dependency 1.0.1. This is a big problem with packages like react, where you need to constantly ensure that there is only one version in your project.
What is the expected behavior?
It should merge the two dependencies, as it would on a fresh install without a lock file. The current workaround is to delete the entire lockfile and re-install, but that also unpins all other versions in the project.
Please mention your node.js, yarn and operating system version.
OS X
The text was updated successfully, but these errors were encountered: