Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

npmrc multiple registries for the same scope

Is it possible to contain multiple registries for the same scope? In my company, we use @mycompany scope for both public NPM registry as well as internal registries.

I tried to do

@mycompany:registry=https://company.registry.com
@mycompany:registry=https://registry.npmjs.org

but this did not work.

like image 766
Kousha Avatar asked Feb 05 '19 22:02

Kousha


1 Answers

No, you cannot. Unfortunately npm can handle only one scope peer registry. But you might use a proxy as Verdaccio for that that handle the distribution for you. https://verdaccio.org/docs/en/uplinks

I will mock an example of configuration using Verdaccio:

I mocked a "company registry" with no external access (http://localhost:5000/).

storage: /Users/test/.local/share/verdaccio/storage_company_registry

auth:
  htpasswd:
    file: ./htpasswd   
packages:
  '@*/*':
    access: $all
    publish: $authenticated

  '**':
    access: $all
    publish: $all
middlewares:
  audit:
    enabled: true
logs:
  - {type: stdout, format: pretty, level: http}

As you can see, no remotes (uplink) configured, it's completely offline.

Then I'll run my proposal, Verdaccio (http://localhost:4873/) that ask first to the company registry and if the package is not found there, it will fetch from the public registry (npmjs).

storage: /Users/test/.local/share/verdaccio/storage_proxy

auth:
  htpasswd:
    file: ./htpasswd
uplinks:
  npmjs:
    url: https://registry.npmjs.org/
  company:
    url: https://company.registry.com

packages:
  '@company/*':
    access: $all
    publish: $authenticated
    proxy: company npmjs  
  '**':
    access: $all
    publish: $authenticated
    proxy: npmjs
middlewares:
  audit:
    enabled: true
logs:
  - {type: stdout, format: pretty, level: http}

As a PoC (I am switching @company by @babel) I run npm install @babel/types --registry http://localhost:4873/. The result is the following

 warn --- config file  - /Users/test/.config/verdaccio/config.yaml
 warn --- Plugin successfully loaded: htpasswd
 warn --- Plugin successfully loaded: audit
 warn --- http address - http://localhost:4873/ - verdaccio/4.0.0-alpha.4
 http --> 404, req: 'GET http://localhost:5000/@babel%2Ftypes' (streaming)
 http --> 404, req: 'GET http://localhost:5000/@babel%2Ftypes', bytes: 0/43
 http --> 200, req: 'GET https://registry.npmjs.org/@babel%2Ftypes' (streaming)
 http --> 200, req: 'GET https://registry.npmjs.org/@babel%2Ftypes', bytes: 0/93375
 http <-- 200, user: null(127.0.0.1), req: 'GET /@babel%2ftypes', bytes: 0/22072
 http --> 200, req: 'GET https://registry.npmjs.org/esutils' (streaming)
 http --> 200, req: 'GET https://registry.npmjs.org/esutils', bytes: 0/23169
 http <-- 200, user: null(127.0.0.1), req: 'GET /esutils', bytes: 0/3854
 http --> 200, req: 'GET https://registry.npmjs.org/to-fast-properties' (streaming)
 http --> 200, req: 'GET https://registry.npmjs.org/to-fast-properties', bytes: 0/8239
 http <-- 200, user: null(127.0.0.1), req: 'GET /to-fast-properties', bytes: 0/1725
 http --> 200, req: 'GET https://registry.npmjs.org/lodash' (streaming)
 http --> 200, req: 'GET https://registry.npmjs.org/lodash', bytes: 0/185410
 http <-- 200, user: null(127.0.0.1), req: 'GET /lodash', bytes: 0/14307
 http <-- 200, user: null(127.0.0.1), req: 'POST /-/npm/v1/security/audits/quick', bytes: 474/146

Your node package manager will speak with (http://localhost:4873/) and Verdaccio will try fo fetch package from the internal registry, the result is 404, in the second iteration will fetch the package from npmjs, resulting in a 200.

Having a proxy registry makes the process more transparent for your team, all is centralized and more efficient, ihmo.

I hope that helps.

like image 102
Juan Picado Avatar answered Oct 13 '22 08:10

Juan Picado