In short, npx sets npm_config_prefix env var, which affects how npm prefix works, and because of this when we spawn nodeenv from scripts started with npx, we get the correct node version, but incorrect npm version.
Please consider the following code:
const { execSync } = require("child_process");
const { join } = require("path");
console.log(
`npm_config_prefix in ENV: "${process.env["npm_config_prefix"]}"\n`
);
console.log(`Current npm version: ${execSync(`npm -v`)}`);
const nodeenvPath = join(__dirname, "nodeenv");
const node = "18.1.0";
const npm = "7.16.0";
console.log(`Expected npm version: ${npm}\n`);
console.log(`Installing nodeenv, please wait...\n`);
execSync(
[
`(if exist ${nodeenvPath} rmdir ${nodeenvPath} /s /q)`,
`python -m nodeenv ${nodeenvPath} --node=${node} --npm=${npm} --with-npm`,
].join(" && ")
);
console.log(
`\n\nNew npm version: ${execSync(
["nodeenv\\Scripts\\activate", "npm -v"].join(" && ")
)}`
);
And if we run it like this:
npx -y cross-env TESTING=123 node index.js
we will get the following result:
npm_config_prefix in ENV: "C:\Users\maxim\AppData\Local\nvs\default"
Current npm version: 7.15.1
Expected npm version: 7.16.0
Installing nodeenv, please wait...
* Install prebuilt node (18.1.0) ..... done.
symbolic link created for C:\Users\maxim\transactions\nodeenv\Scripts\nodejs.exe <<===>> node.exe
* Install npm.js (7.16.0) ...
New npm version: 7.15.1
As you can see, despite nodenv installing everything correctly, we are still using "current" npm that we ran npx with, not the expected or desired one.
If we run the same script without npx, like so:
We will get the expected results:
npm_config_prefix in ENV: "undefined"
Current npm version: 7.15.1
Expected npm version: 7.16.0
Installing nodeenv, please wait...
* Install prebuilt node (18.1.0) ..... done.
symbolic link created for C:\Users\maxim\transactions\nodeenv\Scripts\nodejs.exe <<===>> node.exe
* Install npm.js (7.16.0) ...
New npm version: 7.16.0
Not sure what can or should be done here from the nodeenv perspective. Probably nothing. I just spent quite some time debugging this and thought I'd share. I will probably solve this by clearing all these npm_config_* from env before spawning script that uses nodeenv, will report results.
In short,
npxsetsnpm_config_prefixenv var, which affects hownpm prefixworks, and because of this when we spawnnodeenvfrom scripts started withnpx, we get the correct node version, but incorrectnpmversion.Please consider the following code:
And if we run it like this:
npx -y cross-env TESTING=123 node index.jswe will get the following result:
As you can see, despite nodenv installing everything correctly, we are still using "current" npm that we ran
npxwith, not the expected or desired one.If we run the same script without
npx, like so:We will get the expected results:
Not sure what can or should be done here from the nodeenv perspective. Probably nothing. I just spent quite some time debugging this and thought I'd share. I will probably solve this by clearing all these
npm_config_*from env before spawning script that usesnodeenv, will report results.