39

I'm testing a new version of our npm packages registry. I'd like to run a job in our CI server specifying a registry different of the default.

I tried to execute npm publish --registry "http://nexus.dsv.myhost/nexus/repository/npmjs-registry but it didn't work. It was published to the default registry.

How do I specify a different registry while running npm publish. It is a scoped package.

neves
  • 33,186
  • 27
  • 159
  • 192

3 Answers3

49

There's multiple ways to accomplish this.

  1. use npm config to set the registry globally:

    npm config set registry http://nexus.dsv.myhost/nexus/repository/npmjs
    
  2. use npm config to set the registry for the package scope:

    npm config set @<your scope here>:registry http://nexus.dsv.myhost/nexus/repository/npmjs
    
  3. configure your package.json with a publish config:

    {
      ...
      "publishConfig": {
        "registry": "http://nexus.dsv.myhost/nexus/repository/npmjs"
      },
      ...
    }
    
    
  4. use npmrc to configure the registry

    registry=http://nexus.dsv.myhost/nexus/repository/npmjs
    
Evan Carroll
  • 78,363
  • 46
  • 261
  • 468
Jake Holzinger
  • 5,783
  • 2
  • 19
  • 33
  • 2
    The `npm config` does not work, because I have a shared Node installation. It is a CI server. That would change the configuration for everything that is run in the server. I just want to change it for a specific job. It would be better to configure something at the command line, so I don't need to change the code. – neves Aug 23 '19 at 21:39
  • 3
    Your CI job can generate an `.npmrc` file at the root of the package before attempting to publish if you need this to be specific to the job. I updated my answer to include details about the npmrc file. – Jake Holzinger Aug 23 '19 at 22:04
36

It sounds like you have a scope-specific registry configured somewhere in your npm config.

npm will merge your global, local and CLI-provided config. But any scope-specific config will take precedence over unscoped config regardless of where each of them are defined.

For example, if you have @myscope:registry=xyz in your ~/.npmrc file, that will take precedence over --registry=abc provided on the CLI, because a scope-specific registry always overrides the unscoped registry.

However, you can also pass a scope-specific registry on the CLI itself like this:

npm publish --@myscope:registry=http://nexus.dsv.myhost/nexus/repository/npmjs-registry

Note that because of how nopt (which is what npm uses under the hood to parse the CLI options) parses freeform switches, the = sign here is required. If you use a space instead, it won't work as expected.

daiscog
  • 11,441
  • 6
  • 50
  • 62
1

You can also publish directly to a scoped registry by adding the --scope parameter, where that scope is already defined in your .npmrc file. I could not find any documentation on this feature, so documenting here:

Given .npmrc

@myscope=https://my.custom.registry.url

Command to publish

npm publish --scope=@myscope

This will publish the package to your scoped/private registry.

I found this particularly useful when consuming/creating NPM packages for Azure DevOps / Azure Artifacts feeds, where we have decided to NOT use upstream sources, and instead use scope to pull/push packages to our private registry.

Note that doing it this way requires your private registry to have @myscope/package-name as the actual package names. See this microsoft doc for notes.

Azure Artifacts Example Package

Per the note above, here's how your packages you're creating should look when using scope for a private repo + the public npmjs.org registry.

package.json:

...
  "name": "@myscope/my-private-package",
...
ryancdotnet
  • 2,015
  • 16
  • 33