how to get returned value from npm-scripts? - node.js

In package.json, I have:
"scripts": {
"foo": "echo foo",
"bar": "npm run foo > result.txt"
}
and then if I run npm run bar, I will get the text in result.txt:
> kaze#0.0.55 foo D:\code\kaze
> echo foo
foo
That is not what I expected. What I expected is just:
foo
So, what is the problem with my npm scripts?

When you use >, all stdout of its left command execution would be written to result.txt, including descriptive information shown in the question. It has nothing to do with npm run bar.
If you just run npm run foo > result.txt in command line window, same result would be retrieved.
To only include foo in result.txt, npm option --silent can be used:
"scripts": {
"foo": "echo foo",
"bar": "npm run foo --silent > result.txt"
},

Related

Check file exists before launch it in webpack npm scripts

I have a package.json like this:
...
"scripts": {
"dev": "webpack --config webpack.dev.config.js --mode development --progress --colors",
"postdev": "if (Test-Path \"./postdev.sh\" ) { echo \"file exists\"; ./postdev.sh }"
},
...
How can I check if file "postdev.sh" exists and then launch it in NPM-scripts section?
I run that command in the terminal and it goes correctly, but if I try to launch that npm-script it says "Unexpected appearance: "./postdev.sh"."
on macos or linux try this one for postdev:
"postdev": "test -f ./postdev.sh && echo 'file exisits' && ./postdev.sh",
Finnally found a solution (maybe it works only on Windows, but it is enough for me):
"postdev": "if exist postdev.sh ( postdev.sh )",
You can use path-exists-cli package, a cross-platform tool, to check if a file/directory exists and use && or || after to run the next command if exists or not, respectively:
{
"scripts": {
// other scripts...
"postdev": "path-exists ./postdev.sh && echo 'Exists' || echo 'Does not exists'"
}
}

Propagate arguments to two commands combined with &&

I have two commands in package.json combined with '&&':
"scripts": {
"someAction": "node dist/scripts/actionOne && node -r dist/scripts/actionTwo"
},
Is it possible to call this script from cli, passing arguments to both 'actionOne' and 'actionTwo' ?
When calling
npm run someAction -- firstArg, secondArg args are passed only to 'actionOne' script.
*Number of args expected by actionOne and actionTwo are identical.
After looking at the docs, it looks like npm-run-all would work with argument placeholders.
We can use placeholders to give the arguments preceded by -- to scripts.
$ npm-run-all build "start-server -- --port {1}" -- 8080
This is useful to pass through arguments from npm run command.
{
"scripts": {
"start": "npm-run-all build \"start-server -- --port {1}\" --"
}
}
$ npm run start 8080
> example#0.0.0 start /path/to/package.json
> npm-run-all build "start-server -- --port {1}" -- "8080"
So you could do something like this:
{
"scripts": {
"start": "npm-run-all dist/scripts/actionOne -- --arg {1} && dist/scripts/actionTwo -- --arg2 {2}"
}
}
Then:
npm run start arg1 arg2
If there is a real answer, I wanna know. But also, you can make a script like this
some-action.sh
set -e
dist/scripts/ActionOne $#
dist/scripts/ActionTwo $#
and then put this in your package.json
"scripts": {
"someAction": "bash some-action.sh"
},

Access command line argument in scripts of package.json

I have created a command in package.json file
"create": "ng g component process.env.page --it false"
Now I want to access the passed page argument in the above command so that user can pass the component name to the npm command
I am running the above command as
npm run create --page login
and this runs the
ng g component process.env.page --it false
so new component is created with name process.
How can I access the passed page (login) in my script?
You can use the primitive process.argv or yargs which is a lot more powerful
here is a yargs example
const argv = require("yargs").argv;
let page = argv.page //get the page
The syntax of npm run is:
npm run <command> [-- <args>]
So you need to pass -- before your args. Your command should be as follows:
npm run create -- --page login
const minimist = require('minimist');
let args = minimist(process.argv.slice(2), {
default: {
port: 8080
},
});
run with
npm run start -- --port=8090
args contains
args: { _: [], port: 8090 }

Use babel in Node console

I'm running node 4.6.1 and I'd like to get es6/7/8 syntax in the node console as I can get with Babel. I'm able to compile scripts fine with babel, for instance by running
babel-node ./index.js --presets es2015,stage-0
but I could not find how to get such syntax support in the console. For instance the node console doesn't understand things like
const filter = {...{ foo: 1 }, ...{ bar: 4 } }
or all the async/await things.
When running scripts with npm, npm loads scripts under node_modules/.bin that are not part of the PATH. So running
$ babel-node --presets es2015,stage-0
will fail with
-bash: babel-node: command not found
but
$ node_modules/.bin/babel-node --presets es2015,stage-0
will work just fine. I'll get a node console where I can do:
> const filter = {...{ foo: 1 }, ...{ bar: 4 } }
> filter
{ foo: 1, bar: 4 }
> const a = async () => {}

shell function can't be called in node

I have these:
An shell executable file:
function print() {
echo 1
}
The package.json` file
{
"name": "tests",
"scripts": {
"test": "./shell.sh"
}
}
When I ran npm test on a linux machine, I got this error
> tests# test /home/xxxx/test
> ./shell.sh
./shell.sh: 1: ./shell.sh: Syntax error: "(" unexpected
npm ERR! Test failed. See above for more details.
Why so? Anybody has some insight? I am totally puzzled.
This doesn't really have anything to do with Node or npm, but with the shell script missing the shebang.
Try instead e.g.
#!/bin/sh
# Note the new line above
function print() {
echo 1
}

Resources