-
Couldn't load subscription status.
- Fork 247
Description
Motivation ("The Why")
First, I want mention that I'm very glad for #275 RFC, I believe it can make the NPM ecosystem more open and safer, thank you! While I would agree with #275, but I think adding registry: to all my private packages can be a little tedious, especially if I have multiple packages that are in @myorg Scope and IMO can make package.json harder to read.
So my proposal is to add new key called registryRules in package.json, it is an object that its key acts like a prefix-pattern that will be matched against packages that are in dependencies or *Dependencies, if the package name match the pattern, it will look up the package to the registries that are defined in that particular pattern.
Example
{
"name": "package-name",
// ...
"registryRules": { // <patterns>
"<pattern>": [ // Arrray of <registry>
{
"url": "<registry_url>",
},
// ...
]
}
}A concrete example would be something like
{
"name": "fabulous-package",
// ...
"registryRules": {
"@myorg": [
{ "url":"https://registry.npmjs.org"},
{ "url":"https://registry.example.com"},
],
"@myorg/legacy-app-*": [
{ "url":"https://legacy-registry.example.com" },
]
}
}Details:
-
<registry>object holds the details about the registry, with properties:url:string - the url of the registry
Why an object? This will make future extension easier. Let's say NPM decided to have v10 API, you can add
versionkey to maintain backward compatibility with older API. -
<patterns>is an object, that have a string as the key and<registry>object for the value- It will match the key to the prefix of the package name, so if the pattern is
@myorgis will affect all the dependency that have prefix@myorg, the pattern not limited to Scope name but can also match full package name like@myorg/fabulous-packageas well. - Additional support for wildcard
*, to match the package name, example:@myorg/app-*-demoit will only match@myorg/app-super-demoand not@myorg/app-super
- It will match the key to the prefix of the package name, so if the pattern is
Alternatively, use regex instead of prefix + wildcard patterns.
Implementation details proposal:
<patterns>respect it's key ordering. If a package name match multiple patters it
will search through the pattern that have lowest index, and if the package not found, continue the search to the second lowest index.<registry>inside a<pattern>also respect it's ordering, so if the package found in multiple registry, it will use use registry that have the lowest index number as a tie breaker.- Authentication to the registry still being handled by
npm login. - my suggestion is to match the pattern only for package that are explicitly stated in that
package.json(dependenciesand*Dependencies), it does not affect it's the dependencies of it's package. For example:
Dependency tree for @myorg/package-a
@myorg/package-a
├── @myorg/package-b
│ ├── @myorg/package-x
│ └── @myorg/package-y
└── @myorg/package-c
In this scenario, @myorg/package-a explicitly define the registryRules in it's package.json as
{
"name": "@myorg/package-a",
"registryRules": {
"@myorg": [
{
"url": "https://registry.example.com",
}
]
}
}Thus this explicit registryRules will only affect @myorg/package-b, @myorg/package-c not @myorg/package-x, @myorg/package-y
I have no concrete argument for this, but I think this behavior is easier to grasp compared to propagating the rules to the dependency tree.
Current Behaviour
AFAIK it will try to match given pattern specified in npm login --scope=@organization --registry=registry.organization.com and fall back to NPM public registry if the package is not found.
Related
- [RRFC] Improve experience and security around npx and scoped packages #323
- [RRFC]
registry:<url>#<name>[@<version-range>]dependency specifier #275
And lastly, I just want to point out that something similar but slightly different has been done by other community, I want to point this out, maybe we can get some inspiration or concerns from their implementation: