Marc Thomas
Marc Thomas

Reputation: 289

Failed to replace env in config using Bash & NPM

I'm trying to use a private NPM module in my application, and need to set appropriate NPM access tokens so that third-party tools (Heroku and CI) can access, and install the module.

I have the following line set in my ~/.bash_profile:

export NPM_TOKEN="XXXXX-XXXXX-XXXXX-XXXXX"

and then in the /path/to/app/.npmrc I have

//registry.npmjs.org/:_authToken=${NPM_TOKEN}

However, whenever I open my terminal, I get the following error on startup:

Error: Failed to replace env in config: ${NPM_TOKEN}
    at /Users/marcthomas/.nvm/versions/node/v4.2.1/lib/node_modules/npm/lib/config/core.js:429:13
    at String.replace (native)
    at envReplace (/Users/marcthomas/.nvm/versions/node/v4.2.1/lib/node_modules/npm/lib/config/core.js:424:12)
    at parseField (/Users/marcthomas/.nvm/versions/node/v4.2.1/lib/node_modules/npm/lib/config/core.js:400:7)
    at /Users/marcthomas/.nvm/versions/node/v4.2.1/lib/node_modules/npm/lib/config/core.js:338:17
    at Array.forEach (native)
    at Conf.add (/Users/marcthomas/.nvm/versions/node/v4.2.1/lib/node_modules/npm/lib/config/core.js:337:23)
    at ConfigChain.addString (/Users/marcthomas/.nvm/versions/node/v4.2.1/lib/node_modules/npm/node_modules/config-chain/index.js:244:8)
    at Conf.<anonymous> (/Users/marcthomas/.nvm/versions/node/v4.2.1/lib/node_modules/npm/lib/config/core.js:325:10)
    at /Users/marcthomas/.nvm/versions/node/v4.2.1/lib/node_modules/npm/node_modules/graceful-fs/graceful-fs.js:76:16
/Users/marcthomas/.nvm/versions/node/v4.2.1/lib/node_modules/npm/lib/npm.js:29
throw new Error('npm.load() required')
^

Error: npm.load() required
at Object.npm.config.get (/Users/marcthomas/.nvm/versions/node/v4.2.1/lib/node_modules/npm/lib/npm.js:29:11)
at exit (/Users/marcthomas/.nvm/versions/node/v4.2.1/lib/node_modules/npm/lib/utils/error-handler.js:58:40)
at process.errorHandler (/Users/marcthomas/.nvm/versions/node/v4.2.1/lib/node_modules/npm/lib/utils/error-handler.js:385:3)
at emitOne (events.js:77:13)
at process.emit (events.js:169:7)
at process._fatalException (node.js:221:26)
nvm is not compatible with the npm config "prefix" option: currently set to ""
Run `nvm use --delete-prefix v4.2.1 --silent` to unset it.

However, running echo $NPM_TOKEN returns the correct token, so the variable definitely exists.

If I run source ~/.bash_profile the error disappears, and I can install as normal.

Any help appreciated as I'm bashing my head against a wall at this problem!

Upvotes: 26

Views: 35468

Answers (5)

Jezor
Jezor

Reputation: 3426

Actually proper solution

Update your CI deployment configuration:

npm config set '//registry.npmjs.org/:_authToken' "${NPM_TOKEN}"
npm publish

Remove this line from the .npmrc file:

//registry.npmjs.org/:_authToken=${NPM_TOKEN}

Example build config

You can see this solution used in practice in one of my GitHub repositories: https://github.com/Jezorko/lambda-simulator/blob/5882a5d738060c027b830bcc2d58824c5d27942b/.github/workflows/deploy.yml#L26-L27

The encrypted environment variable is an NPM token.

Why the other "solutions" are mere workarounds

I've seen answers here and under this question that recommend simply removing the variable setting line or .npmrc file entirely.

Thing is, the .npmrc file might not be ignored by your VCS system and modifying it might lead to accidental pushes to your project's repository. Additionally, the file may contain other important settings.

The problem here is that .npmrc does not allow defaults when setting up environment variables. For example, if the following syntax was allowed, the issue would be non-existent:

//registry.npmjs.org/:_authToken=${NPM_TOKEN:-undefined}

Upvotes: 11

Neo Tan
Neo Tan

Reputation: 301

For Windows 10 users

  1. run set NPM_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxx in your cmd prompt OR set it as a environment variable enter image description here
  2. edit .npmrc, a pair of % should be used, good to run npm i now.
//registry.npmjs.org/:_authToken=${NPM_TOKEN}

or (if above one doesn't work)

//registry.npmjs.org/:_authToken=%NPM_TOKEN%

Btw, if you need a fallback solution:

//registry.npmjs.org/:_authToken=%NPM_TOKEN% //<-- depends on your need
//your-corp-registry-url/:_authToken=%YOUR_CORP_TOKEN% //<-- depends on your need
@your-corp:registry=https://npm.pkg.github.com/path-of-your-corp
registry=https://registry.npmjs.com  //<-- fallback registry

Upvotes: 2

Aman Gupta
Aman Gupta

Reputation: 45

I am also getting the same problem when writing any command related to npm. So I solved by node or nodemon . so when you want to start your server use the node and when you want to install any package just remove this and then install it will work.

//registry.npmjs.org/:_authToken=${NPM_TOKEN:-undefined}

It will work in both react and node.js for me. Run react also by node by creating own server.js file like in node.js By this, I successfully deployed my application on Heroku and in production give your env variable on the server where you are deploying and in your own machine put it in .bash_profile and put it in .gitignore

export NPM_TOKEN="XXXXX-XXXXX-XXXXX-XXXXX"

Upvotes: -1

Paul Nispel
Paul Nispel

Reputation: 761

The fix for me was moving export NPM_TOKEN="XXXXX-XXXXX-XXXXX-XXXXX" before my nvm stuff in .bash_profile

from

export NVM_DIR=~/.nvm
source ~/.nvm/nvm.sh
export NPM_TOKEN="XXXXX-XXXXX-XXXXX-XXXXX"

to

export NPM_TOKEN="XXXXX-XXXXX-XXXXX-XXXXX"
export NVM_DIR=~/.nvm
source ~/.nvm/nvm.sh

Upvotes: 49

Ronald Gemao
Ronald Gemao

Reputation: 45

In your case you have to do this rm -f ./.npmrc . This worked for me.

Upvotes: -6

Related Questions