Run npm script with optional params - npm

I want to run a npm script which accepts optional params, and has a fallback for a default values for params that were not passed,
for example:
I have this "example" script defined in my pacakge.json:
"scripts": {
"example": "echo input"
},
I want to pass in the "input" as a parameter meaning:
If I run npm run example --input=true then it'll output true
If I run npm run example without params then it'll output false
I modified my pacakge.json to accept the input parameter:
"scripts": {
"example": "echo %npm_config_input%"
},
now when I run npm run example --input=true or npm run example --input=false
I get 'true' or 'false' respectively, but when I run npm run example the result I get is %npm_config_input%.
I want to give the param a default value so that when its not passed in explicitly - the default value will be used, something similar to :
"scripts": {
"example": "echo %npm_config_input% || 'false'"
},
So that running npm run example will result in 'false'
Is this possible?

You can achieve it using the https://www.npmjs.com/package/#naholyr/cross-env package, which supports default values for variables. On top of that, it will make your script OS-agnostic. Here's how:
"scripts": {
"example": "cross-env INPUT=${npm_config_input:false} npm run _example",
"_example": "cross-env command $INPUT"
},
For a reason yet unknown to me, using echo as the command will not print the variable value. But I'm successfully using this pattern to run sass with arguments, and fallback values, if no arguments are passed.

Related

How to set positional arguments via npm test script in package.json file?

I'm running AVA test now and I have 3 positional arguments that will be passed when running the command.
For example:
npm test <arg1> <arg2> <arg3>
But I wish to put the first 2 positional arguments inside packaga.json file so that I don't have to manually pass in 3 arguments whenever I run the test.
This is how my test script looks like in package.json file:
{
"scripts": {
"test": "ava -v --serial --timeout='2m'"
}
}
I tried this but it's not working:
{
"scripts": {
"test": "ava -v --serial --timeout='2m' -- -- <arg1> <arg2>"
}
}
npm test <arg3>
NOTE: The double '--' is used to separate the ava flags with the arguments. I found this from https://github.com/avajs/ava/blob/main/docs/recipes/passing-arguments-to-your-test-files.md
So, I'm wondering is it possible to achieve this?
The problem was solved. Here's the solution:
{
"scripts": {
"test": "ava -v --serial --timeout='2m' -- <arg1> <arg2>"
}
}
npm test <arg3>
I removed one of the '--' from the script and it works. Not sure why, feel free to tell me if anyone knows it. Thanks!

npm scripts pass dynamic arguments from one script to the other

How can I pass arguments from one script to the other
using npm-run-all (to run in parallel)
scripts:{
"start":"run-p dev watch -- --theme=$themeId",
"dev": "webpack",
"watch": "theme watch --env=$themeId"
}
Then calling start like:
npm run start theme=2233
But it wouldn't pass the argument to the watch argument
Using ${npm_config_themeId}
"scripts": {
"start": "run-p dev watch",
"watch": "theme watch --env=${npm_config_theme}",
}
Then calling
npm run start -theme=123

How to modify npm scripts in package.json for Windows [duplicate]

issue:
in script:
we want to check env. variable {dev/test/mock} and do following script run based on it.
if $mock is true the run script start-mock else go on reach real test server
scenario 1:
we added commands aggregated in package.json script section
e.g. : "test": "export NODE_ENV=dev; grunt", [on linux]
which is "test": "(SET NODE_ENV=dev) & (grunt)", [on win32]
scenario 2:
could be bat/sh script sitting in package and we called them out from package.json
scenario 3: (permanent solution)
not sure if its already available out there
something like
get arguments from script section: to give flexibility and freedom to end user.
e.g. : "test": "solution.env NODE_ENV=dev; solution grunt"
where we can have script to process (input with process.platform) out put depends on OS.
"start-pm2": "if \"%MOCK%\" == \"true\" ( npm run mock & pm2 start process.json --env test ) else ( pm2 start process.json )", [windows] for linux if.. fi
Use: run-script-os
For example:
// from pacakge.json
"scripts": {
// ...
"dist": "run-script-os",
"dist:win32": "tar -C dist -cvzf %npm_package_name%-%npm_package_version%.tgz .",
"dist:linux": "tar -C dist -cvzf $npm_package_name-$npm_package_version.tgz ."
},
Lets consider implementation of 3-th solution like e.g.
package.json
"scripts": {
"command" : "node bin/command.js"
}
bin/command.js
const spawn = require("child_process").spawn
const platform = require("os").platform()
const cmd = /^win/.test(platform)
? `${process.cwd()}\\bin\\command.bat`
: `${process.cwd()}/bin/command.sh`
spawn(cmd, [], { stdio: "inherit" }).on("exit", code => process.exit(code))
depends on environments script will execute command.bat or command.sh
You will need to implement solution 3.
You can use cross-env package that does it for you.

npm - Pass arguments from CLI through multiple scripts

Let's say I have the following in a file called print-last-arg.js:
console.log(process.argv[process.argv.length-1])
And the following scripts in my package.json:
"scripts": {
"print_a": "node print-last-arg.js",
"print_b": "npm run print_a"
}
When I run npm run print_a -- --foo=bar, I get --foo=bar as expected.
However, npm run print_b -- --foo=bar gives me no output.
How do I pass the CLI arguments from print_b to print_a?
It turns out that you just have to add an extra -- on the end of print_b, which will tell npm to pass whatever arguments print_b got to print_a. So,
"scripts": {
"print_a": "node print-last-arg.js",
"print_b": "npm run print_a"
}
becomes
"scripts": {
"print_a": "node print-last-arg.js",
"print_b": "npm run print_a -- "
}
VoilĂ ! Now npm run print_b -- --foo=bar prints --foo=bar as expected.

How can I pass parameters from a npm script to another?

I am trying to pass the parameters from a npm script to another (that is called by the first one), but I absolutely can't figure out how to do it.
Here is the case, I have the following scripts section in my package.json :
{
"scripts": {
"one": "npm run two && npm run three",
"two": "gulp build",
"three": "another random command"
}
}
I'm running script one like this : npm run one -- --arg=value. But I want to dynamically pass down arg to the script two.
To sum up, what I want is :
I type npm run one -- --arg=value
It runs npm run two -- --arg=value && npm run three
Which results in running gulp build --arg=value, followed by the other random command
Does anybody have an idea ? Thank you very much.
All three methods below work with npm run one -- --arg=value.
1. Using pre & post scripts
You can run the second script directly and define the third one as a post script.
{
"scripts": {
"one": "npm run two --",
"postone": "npm run three",
"two": "gulp build",
"three": "another random command"
}
2. Using npm-run-all
Pass argument placeholders to individual scripts.
"scripts": {
"one": "run-s 'two -- {#}' three --",
"postone": "npm run three",
"two": "gulp build",
"three": "another random command"
}
3. Using concurrently
Change the first script to run everything with concurrently, instructing that the second script should get pass through arguments.
{
"scripts": {
"one": "concurrently -P 'npm run two -- {#} && npm run three' --",
"two": "gulp build",
"three": "another random command"
}
}
Since we are passing only one command to concurrently, there is no concurrency.