How to pass argument to npm script with AND operator - node.js

I have one npm script:
scripts: {
"deploy": "npm run build && ./deploy.sh"
}
we can pass an argument to the script: npm run deploy -- --env=prod
but the problem is the command before the AND operator didn't get the argument injected, is there a way to pass the argument with the && operator?
I am expecting a way likeļ¼š
scripts: {
"start": "npm run build -- arg[0] && ./deploy.sh"
}
or any correct or better way to get there, any suggestion will be appreciated.

I try in this way and it seams to work
"start":"npm run build -- {{process.argv}} && ./deploy.sh"

Related

Concatenating command line arguments and flags in NPM package.json scripts

I am looking for a way to do something like this:
package.json
[...]
"scripts": {
"test": "cd ./apps/my-awesome-app && npx cypress run",
"test:watch": "npm run test && --headed",
[...]
so then at the command line, running
npm run test:watch
will result in the following commands being executed:
cd ./apps/my-awesome-app
npx cypress run --headed
However, this is not working as expected. Is there a way to achieve this without repeating the whole "test"-string?

execute several "npm scripts" in order

I would like to command "electron-packer ." (it takes some time) and then "asar pack app app.asar"
Is it possible to do this?
Or should I simply wait for the first one and command the second?
You can queue commands like this.
npm run pack1 && npm run pack2
Or you can add another line that does the above and just run that alone.
"scripts": {
"pack": "npm run pack1 && npm run pack2"
}
Add this inside your "scripts" and you can just run npm run pack to run both of those commands.

Passing arguments to combined npm script

I have in my package.json the following
"scripts": {
...
"prod": "gulp build --production && webpack --env.config=production"
}
I now want to pass a parameter "theme" to both gulp and webpack to be able to adjust the output of the build process from the command line.
I figured out how to pass it to webpack: npm run prod -- --env.theme=themename but gulp does not take care of this. I also played around with the yargs-package, processs.argv and bash string substitution by changing the npm script to "gulp build --production \"$1\" && webpack --env.config=production" but that did not work out either.
How can this be achieved? What am I missing? Any hints highly appreciated!
If you're using Bash you can use a function in your npm-script.
For instance:
"scripts": {
...
"prod": "func() { gulp build --production \"$1\" && webpack --env.config=production \"$1\"; }; func"
}
However, for a cross-platform solution you'll need to consider invoking a nodejs script which exec's the commands - in a similar way shown in Solution 2 of my answer here.

Pass npm script command line arguments to a specific script inside it

I have a scenario where I have to run three npm script to achieve some result in my application. I combined them in one npm script. This is my package.json:
"scripts": {
"setup": "npm install && npm run some-script && npm install",
"some-script": "gulp some-other-script"
}
what I would like to do is to pass arguments to setup script from command line which will be passed further to the some-script script.
If I run npm run script -- --abc=123 the arguments are added at the end of the script but I would like to pass it to specific script (in this case to npm run some-script). I also tried to rewrite script definition like this:
"setup": "npm install && npm run some-script -- --sample=sample&& npm install" but with no luck.
I'm aware of shell functions (described here: Sending command line arguments to npm script and here https://github.com/npm/npm/issues/9627) but I need a solution which will work cross-platform.
Is there a way to do that?
Ok I found a work around.
1st goal was to be able to use some script with arguments, and cascade this to the calls of other scripts :
npm run main -- --arg1
"main": "npm run script1 && npm run script2"
Problem with this approach is that the cascading would only be done by adding the arg passed to npm run main at the END of the line "npm run script1 && npm run script2". I could find no way to pass it to the 1st element : npm run script1
Here is the work around I found :
1st you need to add in package.json:
"config": {
"arg1": "ARG_VALUE"
},
Then in your script you can add it to the call like this :
"main": "npm run script_no_arg1 && npm run scrip1 -- --%npm_package_config_arg1% && npm run script2 -- --%npm_package_config_component% && npm run script_no_arg2"
Finally, You don't need to call it with any arg : npm run main
But you need to modify ARG_VALUE before launc the script :)
Last thing : in my case I was calling gulp tasks :
"cleardown": "rimraf build lib",
"inline-build-templates": "gulp inline-build-templates",
"step1": "npm run cleardown && npm run inline-build-templates -- --%npm_package_config_arg1%",
It works you can get the argument into the gulp task that way :
gulp.task('inline-build-templates', function() {
let component = process.argv[3];
component = component.split('--')[1];
console.log('RUNNING GULP TASK : inline-build-templates for component ' + component);
// whatever task gulp
});
Hope it helps.

Multiple commands in package.json

This command: "start": "node server/server.js" starts my server, but before running this I also want a command to run automatically:
'webpack'.
I want to build a script that can be run with
npm run someCommand - it should first run webpack in the terminal, followed by node server/server.js.
(I know how configure this with gulp, but I don't want to use it)
If I understood you correctly, you want firstly run webpack and after compile run nodejs. Maybe try this:
"start": "webpack && node server/server.js"
The following should work:
"start": "webpack && node server/server.js"
Though, for readability (and especially if you plan on adding additional tasks in the future), you may want to consider creating separate entries for each task and then calling each of those from start. Something like:
{
"init-assets": "webpack",
"init-server": "node server/server.js",
"start": "npm run init-assets && npm run init-server"
}
Better understand the && operator
In my case the && didn't work well because one of my commands sometimes exited with non zero exit code (error) and the && chaining operator works only if the previous command succeeds.
The main chaining operators behave like this:
&& runs the next command only if the first succeeds (AND)
|| runs the next command only if the first fails (OR)
So if you want the second command to run whatever the first has outputted the best way is to do something like (command1 && command2) || command 2
Others OS specific chaining operators
Other separators are different in a Unix (linux, macos) and windows environnement
; UNIX run the second command whatever the first has outputted
; WIN separate command arguments
& UNIX run first command in the background parallel to the second one
& WIN run the second command whatever the first has outputted
All chaining operators for windows here
and for unix here
You can also chain commands like this:
"scripts": {
"clean": "npm cache clean --force",
"clean:complete": "npm run clean && npm uninstall -g #angular/cli && rmdir /Q /S node_modules",
"clean:complete:install": "npm run clean:complete && npm i -g #angular/cli && npm i && npm install --save-dev #angular/cli#latest"
}
Also, along with the accepted answer and #pdoherty926's answer, in case you want to have run two command prompts, you can add "start" before each command:
{
"init-assets": "webpack",
"init-server": "node server/server.js",
"start": "start npm run init-assets && start npm run init-server"
}

Resources