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

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.

Related

Run npm script with optional params

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.

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!

DRY way to change working directory for npm scripts

I'm just trying out NPM as my build system for a small project and I'd like to ask if there is a clean and easy to maintain way to change the working directory for the build scripts. My first thought was something like
"scripts": {
"cd:workdir": "cd src/path/to/my/work/dir/",
"task:1": "npm run cd:workdir && command1",
"task:2": "npm run cd:workdir && command2",
[...]
}
But it seams command* is executed in a different process then npm run cd:workdir, so this doesn't work.
The only working way I found so far is:
"scripts": {
"task:1": "cd src/path/to/my/work/dir/ && command1",
"task:2": "cd src/path/to/my/work/dir/ && command2",
[...]
}
But there must be a better way to do this to keep it DRY and better maintainable. Thanks!
I think you can use child_process.exec to execute some commands from a javascript file:
// task.js
const { exec } = require('child_process');
exec('command', {
cwd: 'src/path/to/my/work/dir/'
}, (error, stdout, stderr) => {
// handle error, stderr...
console.log(stdout)
});
and execute that javascript file using node in npm script: "task:1": "node task.js"

How add variable npm run build in package.json

I have 6 projects in an Angular workspace and I have to build each. Instead of write six lines in my package.json for each projet, for example :
"build_a":" npm run build a"
"buiild_b": "npm run build b"
I would like to create only one line like this :
"build_app": "npm run build name="aaa""
How I can do it ?
you could rely on environment variables in order to discover such names.
however it depends on which operating system you're using on how to define env variables.
"scripts":{
"build:a":"cross-env NAME=a npm run build",
"build:b":"cross-env NAME=b npm run build",
"build:c":"cross-env NAME=c npm run build",
"build":"browserify src/main.js -o build.js"
}
You would end up with a script section more or less like this.
Finally I found the solution using a node.js script: build-subproject.js.
const { exec } = require('child_process');
const args = process.argv.slice(2).join(' ');
console.log(`RUNNING build with args: ${args}`);
exec(
`ng build ${args} && cd dist/${args} && npm pack `,
(error, stdout) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.info(`stdout: ${stdout}`);
}
);
In package.json,
"build-subproject": "node ./build-subproject.js",
Then run , npm run build-subproject my-project-name

Add `jshint` worker into `scripts` for package.json

Dear stackoverflowers.
I have decided to include jshint into my project to helps me detect errors and potential problems in my JavaScript code. I have installed it at the project's root and I'm able to run next code from the console:
jshint --config .jshintrc ./app/
It returns me several notifications.
Then I've decided to create a special section inside my package.json scripts section. It looks like that:
"scripts": {
"jshint": "jshint --config .jshintrc ./app/"
}
And when I try to run
npm run jshint
It returns me an exception...
please check it out https://github.com/npm/npm/issues/6124, you can prevent this error if you set your script with following || true like in code snippet bellow
{
"scripts": {
"test": "jshint || true"
}
}
in this case your script will finish with exit code = 0, and npm will no throw an error