npm config not being updated inside the same npm script - node.js

Let's say I have this npm script:
"test": "npm config set email test#test.com && npm config get email"
After running npm run test I don't see email updated.
Similarly if create bash script like so:
npm config set email test#test.com
npm config get email
and add it to npm script, it still works the same way.
This might be a bash issue, I'm a very new to bash.
Is there a way to make it work - meaning to set the config values and use them in the script?

I think the issue is a bit more complicated. Consider this:
c:\cygwin64\home\qbolec\baro>npm config set email old#email.com
c:\cygwin64\home\qbolec\baro>npm run test
> baro#1.0.0 test c:\cygwin64\home\qbolec\baro
> echo 'before'&& grep '^email' /cygdrive/c/Users/qbolec/.npmrc&& npm config set email test#test.com&& echo 'after'&& grep '^email' /cygdrive/c/Users/qbolec/.npmrc&& echo 'get'&& npm config get email
'before'
init.author.email=qbolec#gmail.com
email=old#email.com
'after'
init.author.email=qbolec#gmail.com
email=test#test.com
'get'
old#email.com
c:\cygwin64\home\qbolec\baro>npm config get email
test#test.com
c:\cygwin64\home\qbolec\baro>cat package.json
{
"name": "baro",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo 'before'&& grep '^email' /cygdrive/c/Users/qbolec/.npmrc&& npm config set email test#test.com&& echo 'after'&& grep '^email' /cygdrive/c/Users/qbolec/.npmrc&& echo 'get'&& npm config get email"
},
"author": "Jakub Łopuszański <qbolec#gmail.com>",
"license": "ISC"
}
It looks like the .npmrc file is actually changed by the npm config set immediately, and the change is permanent, but not available for reading through npm config get. However, I don't know how to overcome this.

Related

nodejs, custom global cli not work if i call it

i tring to create a personal global cli in nodejs. after read differents tutorial, i have tried to do it but not have console log printed in my terminal.
i have created a project npm with this package.json
{
"name": "npm-versioning",
"version": "1.0.0",
"description": "",
"main": "index.js",
"preferGlobal": true,
"bin": {
"vf-release": "./bin/cmd.js"
},
"scripts": {
"pretest": "node ./bin/cmd.js",
"test": "echo \"TEST ROOT\"",
"posttest": "vf-release",
},
}
this is the project tree
how can you see in my package.json i have created a bin command called "vf-release", this is connected al file js "bin/cmd.js"
cmd.js
#!/usr/bin/env node
console.log("AAA");
console.log("BBB");
the cli file is very easy. but now the problems,I premise that i work in window, but the same fail is in my "WSL Ubuntu machine" (so, is not a problem of windows!)
if i run "npm run test" on windows or unix i have always the same result
"C:\Program Files\nodejs\npm.cmd" test
npm-versioning#1.0.0 pretest C:\xampp\htdocs\personal\npm-versioning
node ./bin/cmd.js
AAA
BBB
npm-versioning#1.0.0 test C:\xampp\htdocs\personal\npm-versioning
echo "TEST ROOT"
"TEST ROOT"
npm-versioning#1.0.0 posttest C:\xampp\htdocs\personal\npm-versioning
vf-release
Process finished with exit code 0
pretest work (nodejs + js file)
test not matter
posttest use global cli but not write nothing!!
also if i launch the command (linkedin global npm directory) nothing happen.
which is my error?
SOLUTION FIRST STEP: install -g
npm install -g .
C:\Program Files\nodejs\vf-release -> C:\Program Files\nodejs\node_modules\npm-versioning\bin\cmd.js
npm-versioning#1.0.0
updated 1 package in 1.176s
now, if i use "vf-release" in my console i see:
vf-release
AAA
BBB
ok, but if i use a "npm run version" in another app nothing appen!, for example
app-another (package.json)
"scripts": {
"version": "vf-release"
},
the script write :
npm run version
test-app#1.0.0 version C:\xampp\htdocs\personal\npm-test-app
vf-release
why npm run somecommand work inside project, but not work in other run app?

How to use command line params while running npm for 2 scripts

I have the following scripts in the package.json:
"scripts": {
"test" : "npm run module1 || npm run posttest",
"createenv": "node cliTest.js && npm run test"
}
cliTest.js has the following:
console.log(process.argv);
I need to run createenv first to create an env file that will be used by the script 'test'. The problem is that the arguments in the CLI are not made available.
So, if I run the following:
npm run createenv foobar
I get the following and I do not see 'foobar'
[
'/Users/xxxxx/.nvm/versions/node/v16.13.2/bin/node',
'/Users/xxxxx/Documents/core/cliTest.js'
]
How can I retrieve the value foobar from the CLI in my cliTest.js file?
If you really need this &&-chain you can try npm_config_, something like this:
"createenv": "node cliTest.js ${npm_config_name} && npm run test"
then run the command:
npm run createenv --name=foobar
the last argument in console.log should be foobar.

NPM: How can I hook SET NODE_ENV in package.json's prestart script?

I have a basic App created using npm init -y. In package.json I have a main entry which points to server.js.
{
"name": "rest-api",
"version": "1.0.0",
"description": "",
"main": "server.js",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"prestart": "SET NODE_ENV=dev"
}
I am trying to set the NODE_ENV variable in prestart and let npm to call main to invoke npm start. But environment variable set in the prestart is not carry forwarded and is undefined. When I run 'npm start', console outputs that both commands are executed in order.
PS D:\test\RestAPI> npm start
> rest-api#1.0.0 prestart D:\test\RestAPI
> set NODE_ENV=dev
> rest-api#1.0.0 start D:\test\RestAPI
> node server.js
undefined
[undefined] Listening on http://localhost:3000
but when I print the variable from the app, it is undefined. Is there anything that I am doing wrong here, or is this how it is supposed to behave? Is there a way to invoke and set env variable using 'SET NODE_ENV=dev' without chaining it to 'node server.js'
When I combine both in the 'start' as below, then the environment variable is set.
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "set NODE_ENV=dev && node server.js"
}
I am testing this on Windows 10, npm version 3.10.10. Appreciate your help.
I know how this can be done in package.json using 'start'. This question is specific to how this can be achieved through 'prestart'.
Thanks.
The short answer is NOT possible.
1. Why :
this is not be possible because each script executed by different processes that npm spawns for this purpose which has its own environment variables.
To realise that, create test project and configure both scripts to be like
"start": "pause&&set VAR1",
"prestart" : "pause&&set VAR1=value&&set VAR1&&pause",
On windows open the task manager and pay close attention how many cmd process es are listed before running the script.
run the command "npm start" and at each request "press any key to continue..." just notice how processes created are created. I attached screenshots for this in order
2. Unless :
you change how npm executes different scripts to use one cmd for all the scripts which I think is complicated and probably will create bugs.
If you want to chain scripts and add env variables along the way then checkout the example given in the cross-env package:
{
"scripts": {
"parentScript": "cross-env GREET=\"Joe\" npm run childScript",
"childScript": "cross-env-shell \"echo Hello $GREET\""
}
}

How to get environment variable in npm script?

I am trying to access an enviroment variable in the npm script itself like so:
"scripts": {
"test": "istanbul cover node_modules/.bin/_mocha --root ../SERVER/routes -- --recursive"
},
And start this script like so:
SERVER=somewhere npm test
How can I get the resolved value of SERVER variable in the npm script in the package.json itself?
For the windows users, you may use your variables like this: %SERVER% instead of $SERVER.
Or better approach to use cross-env module which will allow you to do it like linux on all platforms:
npm i cross-env
And use it :
"scripts": {
"test": "cross-env-shell \"istanbul cover node_modules/.bin/_mocha --root ../$SERVER/routes -- --recursive\""
}
Will using $SERVER work for you?
"scripts": {
"test": "istanbul cover node_modules/.bin/_mocha --root ../$SERVER/routes -- --recursive"
}

How do I set the default test command for `npm init`?

I know I can do:
npm config set init.author.email me#mycompany.com
npm config set init.license UNLICENSED
To set the defaults used to create a new package.json with npm init. But how can I set the default value for the test command? I've tried
npm config set init.scripts.test "mocha"
But it doesn't work. The npm docs don't seem to help.
Is there a list of all the init defaults?
There is a list of all config defaults npm config list -l.
As you can see there isn't anything like init.scripts. But there is another way to do it. If you first npm install mocha and then npm init you will get a package.json like:
{
"name": "asd",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {},
"devDependencies": {
"mocha": "^2.4.5"
},
"scripts": {
"test": "mocha"
},
"author": "",
"license": "UNLICENSED"
}
Although you can't (currently) configure default scripts via npm settings, you can customise the entire npm init output by providing your own init-module. The default is stored at ~/.npm-init.js - whatever you export becomes the result of running npm init.
To make this useful, you'd probably want to hijack the existing default npm init module, which lives in <your npm install directory>/node_modules/init.js. If you only care about providing a default test script, the simplest option is to use init-module, which provides a configuration parameter init-scripts-test.
I was searching for a way to programmatically create a package.json with dynamically defined values. I noticed creating a package.json file before calling npm init -y works as expected.
// Require: fs
const fs = require('fs')
// Variables
const values = {
"scripts": {
"test": "mocha"
}
// as well as any other values you want
}
// Create package.json
fs.writeFileSync('package.json', values)
Running npm init -y after running the above code would generate a package.json with scripts.test = "mocha" defined.
If you're looking for a way to run npm init -y from within code as well, I recommend using shelljs: shell.exec('npm init -y').
npm config set init ... will create a default configuration for all future projects that will be initialized - if you want to just set a few values once - simply use a shellscript to write some values prior to npm init like so:
echo '{"version":"0.1.0","license":"UNLICENSED","private":true,"scripts":{"test":"npx jest"}}' > "./package.json" && npm init -y

Resources