-
Notifications
You must be signed in to change notification settings - Fork 240
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
RFC: Vendoring dependencies #642
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Vendoring is a resoundingly bad practice that npm should not in any way encourage or ease - there's a reason checking node_modules into version control is similarly discouraged.
With a lockfile, and an internal registry, there should be no issues with reproducibility I'm aware of. Can you elaborate on what I might be missing here?
|
||
To my knowledge, there are two alternatives: | ||
1. Ship `node_modules`. This would work a good percent of the time, assuming `npm ci --ignore-scripts` is used, and all packages are installed across all operating systems. | ||
2. Generate a cache, and point npm to that. Given that the cacache format hasn't changed in a number of years, nor has what npm stored in cache entry metadata, I'd say this is a pretty safe bet. However, I feel uneasy about relying on it, as it could break at any time. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the third option is the best practice for a long time - use a lockfile, and an internal registry, and any resulting differences between systems of node_modules
are intentional and necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand that there are differences between different node_modules
, but having to run an internal registry certainly begs for a more lightweight solution, IMHO. (Why use an internal registry over the public one, assuming all of your dependencies are there, if you have a lockfile?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because deploying from the internet is hugely unsafe and exposes you to DNS/man-in-the-middle attacks?
Any discussion about reproducibility rests on first having no uncontrolled sources of content.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How is this the case with a known-good lockfile, which contains hashes for all dependencies, though?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's fair, but you still don't want the contents denied to you entirely - that breaks your build too.
Sure. The motivation for this RFC is my effort to rework how we package npm projects in Nixpkgs -- which presents certain challenges surrounding reproducibility. The current solution used is to generate large files (warning: 6 MB file) containing dependency trees. I've proposed an alternate solution which does what I've described as the second alternative -- generating a cacache using a small, purpose-built fetcher, which only relies on a lockfile. (I've done it this over e.g. shelling out to npm to further ensure reproducibility.) This has proven to work very well for this use case, which is great. But as I said, relying on this is a worse idea than an official solution, since the (historically very low) chances of breakage are there. We currently use similar solutions for Go, Cargo, and Yarn (v1), utilizing the aforementioned vendoring solutions for the first two, while a home-grown(-ish?) solution for Yarn. (I'm guessing this comes off as selfish if I'm only doing it for this reason, but I also believe that Go and Cargo must have implemented this for a good reason.) |
Why do you(/others, I'm assuming) believe this? Assuming the vendored dependencies include any and all dependencies that are required for the project, no matter the OS etc, it provides more reproducibility than checking in |
Reproducibility isn't remotely more important than a manageable git repository or a navigable/comprehensible git diff/log. |
Sure, but alternate uses exist, which is evident by Cargo producing a tarball as opposed to a folder. |
Is this functionally any different than including all of your dependencies as bundled and running |
I don't believe so, except for the fact that I think the two serve different purposes, though, and one doesn't require modifying existing projects. |
If there is a potential for having things |
Right, but it still depends on the local state of the |
Yep. And if that's a problem, then that's the problem to fix. |
Looks like I made a pretty dumb factual error here -- both Cargo and Go use folders. I'll push a revision fixing that, as well as also mentioning |
Fixed. |
Rendered