Skip to content

Commit 3d7640f

Browse files
committed
RFC: Vendoring dependencies
1 parent d8a72cc commit 3d7640f

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

Diff for: accepted/0000-vendoring.md

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Dependency vendoring
2+
3+
## Summary
4+
5+
Provide a mechanism to vendor all dependencies for a project in a more reproducible form than adding `node_modules` to version control.
6+
7+
## Motivation
8+
9+
A `node_modules` directory can differ between operating systems(/npm versions?), which presents pitfalls for projects that want to ensure full reproducibility of a given dependency tree, such as [Nixpkgs](https://github.com/NixOS/nixpkgs).
10+
11+
## Detailed Explanation
12+
13+
This would add a new command to the npm CLI, `npm vendor`. This command results in a reproducible {archive, directory} that contains all dependencies of the given project. Additionally, a configuration value will be added. When `npm install` and `npm ci` are ran with this value set to a valid path, they will pull from the vendored copies of dependencies.
14+
15+
## Rationale and Alternatives
16+
17+
To my knowledge, there are two alternatives:
18+
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.
19+
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.
20+
21+
Given the pitfalls to these alternatives, I think having an official, sanctioned vendoring mechanism is the best solution.
22+
23+
## Implementation
24+
25+
Pacote will need to be changed to support pulling from vendored copies of dependencies, similar to how `make-fetch-happen` pulls from cacache when possible.
26+
27+
A command will need to be added to facilitate the generation of vendored dependencies.
28+
29+
This will also require a new module to be created to share schemas between the two entrypoints -- unless it fits in an existing one?
30+
31+
## Prior Art
32+
33+
### Go's [`go mod vendor`](https://go.dev/ref/mod#go-mod-vendor)
34+
35+
Go's dependency vendoring solution creates a directory. The contents of directory, for the same project (which means same `go.sum`, their lockfile), has changed between major Go versions. This is something we'd ideally avoid.
36+
37+
### Cargo's [`cargo vendor`](https://doc.rust-lang.org/cargo/commands/cargo-vendor.html)
38+
39+
As a contrast to Go, Cargo creates a tarball with the vendored dependencies. To my knowledge, these tarballs have never changed between Cargo versions.
40+
41+
## Unresolved Questions and Bikeshedding
42+
43+
- What format should we use (tarball or directory)?

0 commit comments

Comments
 (0)