-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Shrinkwrap file from added packages are ignored #838
Comments
We investigated this in #41. Unfortunately the npm shrinkwrap format is poor and very lossy so we can't accurately reconstruct the dependency graph with just the shrinkwrap so we can't support this without crippling other behaviour. |
So you prefer to install broken packages instead? No warning given? If you can't support it, I'd suggest you detect this, and abort the install since it will otherwise be broken. Also, do you have a yarn compatible solution for package authors that desire to specify exact dependencies versions? |
Why would they be broken? If the library wants to pin dependencies to a specific version it could just declare those in the |
@kanongil I wanted to add a little bit to what @kittens and @Turbo87 said above. I've thought a lot about recursively using lockfiles (shrinkwrap or otherwise) when resolving an application. The first time I remember writing about it was in 2010, pretty soon after we first released a version of Bundler with lockfiles generated by default: Clarifying the Roles of the .gemspec and Gemfile. At the time, my TLDR was:
This blog post had a pretty clear directive (that the Ruby community has more-or-less followed) but the reasoning was a little muddled by accidental aspects of the implementation at the time. I had a chance to revisit this question when designing Cargo, which doesn't separate the application manifest from package manifests. For context:
We had an opportunity to think through the problem again from scratch, and control exactly packages would be possible on the registry, and arrived at the same conclusion (described more articulately).
In short, if yarn allowed the The If a package wants to insist on a specific version of a dependency because it needs that version, it should say so in the The nice thing about this philosophy is that it gives packages a very simple way to express either intent:
|
Suppose Package A depends on v1.0.0 of Package B. The author of Package A wants to pin dependencies, so they declare a specific version in package.json: {
"name": "A",
"dependencies": {
"B": "=1.0.0"
} But now suppose Package B has a loose dependency on Package C: {
"name": "B",
"version": "1.0.0",
"dependencies": {
"C": ">2.0.0"
}
} Suppose version Then version |
This problem is exactly the problem that we solved in Bundler and Cargo by using "conservative updating", which avoids updating dependencies unnecessarily across the entire graph. I mentioned it briefly in #579:
The TLDR is that the current structure of the lockfile deterministically finds the same package for a given pattern, but isn't a graph of dependencies themselves. I'm working on #579, which should make it possible to address the scenario you described in the canonical way 😄 |
@wycats thanks for the clarification! just to make sure: your recommendation is to use lockfiles only for "binaries", but not necessarily for libraries, correct? |
@Turbo87 I think it's fine to use lockfiles in libraries if what you're trying to accomplish is increasing the determinism of the library's test suite, for example. That said, in my view you should only do that if you have a matrix of a bunch of different dependencies and lockfiles associated with them. |
As an example, the gem that the Skylight product I work on uses has this gemfile:
- gemfiles/Gemfile.rails-3.0.x
- gemfiles/Gemfile.rails-3.2.x
- gemfiles/Gemfile.rails-4.0.x
- gemfiles/Gemfile.rails-4.1.x
- gemfiles/Gemfile.rails-4.2.x
- gemfiles/Gemfile.rails-5.x
- gemfiles/Gemfile.sinatra-1.3.x
- gemfiles/Gemfile.sinatra-1.4.x
- gemfiles/Gemfile.grape |
Not to overcomplicate things for you @wycats, but I'd be remiss if I didn't at least mention preferred versions as an approach to considering information from deps' lockfiles. |
Wow, thanks for taking the time to look into this, and I generally agree that libraries should not lock their dependencies. The problem is something like Note that since the exact versions of sub-dependencies are desired, it can not be expressed in If you don't want to support this feature, you should at the very least explicitly warn users that are adding / updating a package that contains an ignored |
@kanongil since npm@3 and yarn are flattening the dependencies |
@Turbo87 Hmm, you might be right. I will have to look into this. Still, yarn should warn whenever it ignores a shrinkwrap file. |
@Turbo87 Edit: This does not work at all, as yarn will install newer sub-dependencies into each declared dependency. See #681. It does sorta work for |
@kittens I checked out #41 and it seems the problem is that the shrinkwrap file is computed after dependencies are hoisted. I don't quite grok, however, why this precludes its being used in lieu of a yarn lockfile (I don't doubt it, I just want to take a moment to learn more about yarn and how it flattens its deps and calculates the dependency closure and used lock files and stuff). To my untrained mind, it would seem that you could count on the shrinkwrap to describe a valid closure for a library or app, and if yarn followed that pattern you would get a correct, deterministic dependency closure, with the downside being that you might not get an optimally flat structure (since it might have been better to hoist some deps). |
Can this be reopened please? |
At the very least, I need to be able to generate my lockfile from the contents of my node_modules directory (which is currently managed by npm-shrinkwrap.json but my company is trying to move away from shrinkwrap to yarn. we can't until there's a reasonable transition from one to the other). |
Yarn is useless to me when I can't trust the install command to fetch the right modules, or at least warn that it has done something dubious. @kittens can you reconsider this issue? |
Thank you for raising this issue, @kanongil. I am publishing a security-sensitive library and need to provide reproducible builds to my users. I first looked at
I then found Yarn, read many reviews comparing it favorably to shrinkwrap, and saw that it incorporates hashes in the lockfile. I assumed it would give me the reproducible builds I require for the users of my library. My rationale is the same as that expressed by the maintainer of Hapi. I drank the Kool-Aid after reading the following points and want to provide all of these benefits for my users as well as my developers.
I'm now warning my users not to use Yarn to install my library until this is addressed. |
Here's someone else who feels the same way and wrote an essay about it: |
What I especially don't get is how this issue has been handled, compared to the stated goals of the project. Closing it here doesn't make it go away, but instead actively discourages contributions and adoption. Though, I guess you also gain some immediate adoption from the the fake trust you instill into outsiders? |
@Turbo87 I appreciate the time @wycats took to write a response but, while lengthy and interesting, it doesn't actually attempt to solve the issue. Right now I'm just interested in the project acknowledging that there is an issue. Once it has been acknowledged, work might start on a solution which could be any of these:
|
I respect the authors' decisions to design Yarn however they like and I won't use it if it doesn't address my needs. I'm grateful for the work they've done and the conversations they've inspired (including this one). I respectfully point out that there may be a useful distinction between:
vs.
I see these as two different activities and I would love it if Yarn would present them as explicit options rather than conflating them into a single command. I also agree with @kanongil that for Yarn to be a well-behaved part of the npm community it should display a warning that it is disregarding |
Yarn does warn that |
No it doesn't warn for added packages, only for your local project. |
…Types` with `PropTypes` from 'prop-types` also ignore yarn.lock
Yarn's decision to not respect npm-shrinkwrap means that older modules are just broken unless they're explicitly updated to support yarn. This is honestly a really terrible decision. I just ran across tons of breakages because of this. |
Dependabot alerts are not applied to the users’ apps for the following reasons: 1. We do not have any actual dependencies in our SDK, just peer and dev dependencies, which do not get installed in the user apps. 2. Supposedly we had a dependency in the future, the package manager will not respect the versions in our yarn.lock, since the dependency resolution will be done in the user’s app according to our package.json not yarn.lock. (*) References: (*): A comment by one of Yarn creators, explaining the dependency resolution in an app vs a library: yarnpkg/yarn#838
Dependabot alerts are not applied to the users’ apps for the following reasons: 1. We do not have any actual dependencies in our SDK, just peer and dev dependencies, which do not get installed in the user apps. 2. Supposedly we had a dependency in the future, the package manager will not respect the versions in our yarn.lock, since the dependency resolution will be done in the user’s app according to our package.json not yarn.lock. (*) References: (*): A comment by one of Yarn creators, explaining the dependency resolution in an app vs a library: yarnpkg/yarn#838
Do you want to request a feature or report a bug?
Bug.
What is the current behavior?
Yarn doesn't respect the
npm-shrinkwrap.json
contained inside added dependencies, like hapi, and chooses to install the latest semver compatible versions declared in itspackage.json
instead.If the current behavior is a bug, please provide the steps to reproduce.
yarn add <package-with-shrinkwrap>
What is the expected behavior?
Installation of the exact versions declared in
npm-shrinkwrap.json
, including sub-dependencies. Alternatively, a visible warning that the file has been ignored, and the install might be broken due to this.Note that it is an important feature that a package can specify the exact dependency version requirements.
Please mention your node.js, yarn and operating system version.
yarn v0.15.1
The text was updated successfully, but these errors were encountered: