8

Lets say I have a private npm repository, hosted within JFrog artifactory: https://my-domain.com/artifactory/api/npm/my-repo. In this repository I published one npm package: my-package, which builds fine. my-package has a dependency (or more) to public npm packages e.g. lodash.

However, when I create a new project and attempt to install my-package I get the following error:

$ npm install my-package --registry https://my-domain.com/artifactory/api/npm/my-repo
npm ERR! code E404
npm ERR! 404 Not Found - GET https://my-domain.com/artifactory/api/npm/my-repo/lodash - not_found
npm ERR! 404
npm ERR! 404  'lodash^4.17.11' is not in the npm registry.
npm ERR! 404 You should bug the author to publish it (or use the name yourself!)
npm ERR! 404 It was specified as a dependency of 'my-package'
npm ERR! 404
npm ERR! 404 Note that you can also install from a
npm ERR! 404 tarball, folder, http url, or git url.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\<username>\AppData\Roaming\npm-cache\_logs\2019-04-29T12_47_51_647Z-debug.log

It appears as though npm is searching within my private repository for all the dependencies my-package requires when I specify the --registry option when running an npm install. However, my-package is dependent upon public dependencies, which are not in my private registry.

My Question

How to install an npm package from a private registry that has public dependencies? Perhaps this is also just a JFrog issue?

Any help would be greatly appreciated!

Nathan
  • 7,853
  • 4
  • 27
  • 50
ysfaran
  • 5,189
  • 3
  • 21
  • 51

2 Answers2

3

By specifying a registry with: --registry https://my-domain.com/artifactory/api/npm/my-repo npm is attempting to resolve all necessary packages, by name and version, from your private repository location: domain.com/artifactory/api/npm/my-repo.

To resolve these public dependencies which your private library depends upon you have two options:

  1. Set up a Virtual Npm Registry. (Recommend this approach)
  2. Package all necessary dependencies within your private repository.

A Virtual Repository defined in Artifactory aggregates packages from both local and remote repositories. This allows you to access both locally hosted npm packages and remote proxied npm registries from a single URL defined for the virtual repository.

By setting up a virtual repository which references both your private repository location and the default public npmjs location you will be able to download your private libraries as well as any public npm package by specifying your above mentioned registry.

Since you mentioned JFrog take a look at their confluence page which walks you through the process of creating a virtual repository.

However, if you decide to use option 2 you will have to package all the necessary dependencies within your private repository. Then your private library will be able to properly pull the dependencies it's dependent upon. I would advise against this approach since you will be duplicating work already provided by npmjs and you will additionally have to keep updating your private repository to include new libraries or newer versions of existing libraries.

Hopefully that helps!

Nathan
  • 7,853
  • 4
  • 27
  • 50
  • 2
    There is also a third option which are [npm scoped packages](https://docs.npmjs.com/misc/scope). Thats the solution that I actually came up with because it was the most suitable in my case. The only downside for me was, that I had to rename my packages to scope packages. (`@scope/...`) – ysfaran Jun 24 '19 at 07:19
  • 5
    Not sure if this is exactly what @ysfaran meant, but in my case I was using an `.npmrc`, and the solution was to specify the private registry address for my organizational scope using this line: `@my-org:registry=https://npm.pkg.github.com/my-org`. This way, within my `package.json` the package `@my-org/my-package` is the only one to be retrieved via the private registry, and all other packages are retrieved from the default public registry. – Charles Dec 28 '20 at 09:42
  • 1
    I double @Charles comment. This should be the answer as this is the most easiest way to solve the problem. Then you have your package publish with `@your-org/your-package` and can `npm install @your-org/your-package` afterwards. – MasterWil Jan 12 '21 at 17:52
1

My solution...

involved updating my .npmrc file:

I changed registry=https://npm.pkg.my-domain.com

to @my-private-scope:registry=https://npm.pkg.my-domain.com

Here's why

In it, I had specified that registry=https://npm.pkg.my-domain.com (followed by my auth token) so that I could import a private package from the @my-private-scope scope. However since i left at the @my-private-scope: part, I was changing the URL for all decencies, not just the ones that are part of my private organization. I made the change to specify the my-domain URL for only the dependencies at that scope.

romtunnels
  • 11
  • 1