7

Within Node.js, I would like to read the value of the registry property that npm uses to determine where to download packages.

const registry = someApi.get('registry');

I want to know so that I can create a preinstall script that ensures developers are downloading packages through the local Artifactory instance rather than directly from npm.org.

const EXPECTED_REGISTRY = 'https://example.com/artifactory'
const registry = someApi.get('registry'); 
if (registry !== EXPECTED_REGISTRY) {
   console.log('Please configure your .npmrc to use Artifactory');
   console.log('See http://example.com/instructions');
   process.exit(1);
}

One way to do it would be to shell out to npm config list --json. There must be an API that will give me the same result. I'm just having trouble finding it.

4 Answers 4

9

While there's already an accepted answer, I'll post an alternative answer for posterity.

If you run your script using the npm command and a script added to the scripts property of your package.json file, then your NPM config properties should be accessible to your NodeJS script via the pattern process.env.npm_config_*.

For example, given this package.json file:

{
  "scripts": {
    "start": "node -p \"process.env.npm_config_foo\""
  }
}

When the following commands are run:

npm config set foo bar
npm start

The output is:

> @ start /Users/anonymous/projects/my-package
> node -p "process.env.npm_config_foo"

bar

Note that if your scripts property is not one of NPM's well-known properties (e.g. test, start), you'll need to use npm run <script-name> instead of npm <script-name>.

Reference: https://docs.npmjs.com/misc/config

Sign up to request clarification or add additional context in comments.

6 Comments

process.env only works for me if the settings are set via environment variables with the export command. Otherwise they are not there.
@ADJenks - Refer to point no. 4 in the "Detailed Explanation" section of rfc 0021 where it states that NPM’s intention was/is to "Remove all npm_config_* values from the script lifecycle environment except...". So that may be why they are not there.
@ADJenks, the context of the original post, and my answer, is how to read npm config (.npmrc) values – not system environment variables.
@RobC thanks for pointing that out. @Dan Mork, Yes I know. My point is that when I follow your instructions it doesn't work. I run npm config set foo bar and if I run the script to output process.env.npm_config_foo it says undefined. It doesn't seem to work because of what RobC mentioned. npm_config_* variables are no longer available. The only way I can force the process.env.npm_config_* variables to be available now is to set them via export in bash.
@ADJenks I just tested the answer and it still works using NodeJS/NPM v16.17.0/8.15.0, v17.9.1/8.11.0, and v18.9.0/8.19.1. Perhaps you're not launching your script via npm start or other package.json "scripts" property value and are using node directly instead.
|
6

I'm quite certain you'll have to "shell out", there's no other API that I'm aware of.

You can utilize nodes execSync() or exec() methods to execute the npm config sub-command get, i.e:

$ npm config get registry

Node example using execSync():

const execSync = require('child_process').execSync;

const EXPECTED_REGISTRY = 'https://example.com/artifactory';
const registry = execSync('npm config get registry',
    { stdio: ['ignore', 'pipe', 'pipe'] }).toString().replace(/\n$/, '');

if (registry !== EXPECTED_REGISTRY) {
  console.log('Please configure your .npmrc to use Artifactory');
  console.log('See http://example.com/instructions');
  process.exit(1);
}

Notes:

  1. The execSync() option stdio is configured to prevent logging the returned registry value to the console.
  2. The regex /\n$/ is utilized to remove the new line character.

Comments

1

There's this npm package, no need to shell out as in the accepted answer:

https://www.npmjs.com/package/libnpmconfig

You can even import the npm package in your node script, do an npm.load() and then npm.config.get(<whatever-key>).

5 Comments

While the package is not deprecated the repository is readonly
It isn't clear (to me at least) from the OP's question whether they wanted a way, any way, to get a value from the registry, or to learn the programmatic way to do so themselves without additional package installation. This package does this for you as a black box, you don't need to know the internal implementation.
You are right, but what does it have to do with what I said?
@RazLuvaton your comment suggests (to me, at least) that the OP wanted to learn how to do it programmatically, and of course, if that's the case, my answer is not helpful, since, as you pointed out, the repo is read-only.
In that case I agree
0

Values saved in a config block can be accessed inside of npm scripts by prepending "npm_package_config_".

For example

{
  "config": {
    "fooVar": "abc123"
  }
  "scripts": {
    "echo": "echo $npm_package_config_fooVar"
  }
}

> npm run echo
> abc123

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.