Inject argument into npm script command - node.js

I have an npm script that looks like:
"scripts": {
"example": "webpack-dev-server --content-base examples/embeddable/"
},
I'd like to form the --content-base argument dynamically based on whatever's passed when calling the npm script, like:
npm run example -- embeddable
I know the -- syntax works for making args available to process.argv, but I'm not calling a Node script here so I'm not sure how to access them when forming the command. Does anyone else know of a good, cross-platform way to do this? (Must work on Windows 7, i.e. without bash capabilities.)

This should work ($1 is replaced by whatever you add as first parameter):
"scripts": {
"example": "webpack-dev-server --content-base examples/${1}/"
},
Run it like this:
npm run example -- embeddable

Related

How can I pass a string as an argument to an NPM script that is then passed to a CLI command?

I'm setting up a new react project, and I'd like to use the generate-react-cli package so that I can easily generate components instead of manually having to create files.
However the command to run the tool is lengthly, so I'd like to cut that down using an NPM script. The command is npx generate-react-cli component Box
So preferably I'd like to be able to do something like npm run grc Box and then have "Box" be passed as an argument to an NPM script that looks like
"scripts": {
"grc-c": "npm generate-react-cli component $1"
},
I've tried this using -- parameters but it didn't work as it parses it incorrectly.
You can revert the script to:
"scripts": {
"grc-c": "npm generate-react-cli component"
},
And use:
npm run grc-c -- Box

Using subdependencies in npm script

Say I have a private npm package, #myprivate/repo which has the following contents in its package.json:
"scripts": {
"example": "db-migrate"
},
"bin": {
"foo": "bin/foo"
}
Where bin/foo is:
#!/bin/bash
npm run example
I now pull this into a parent repo with npm install:
package.json:
{
"dependencies": {
"#myprivate/repo": "*"
},
"scripts": {
"example": "unrelated command",
"useful": "foo"
}
}
Then running npm run useful results in the foo bin script getting called, which then attemps to call unrelated command. How do I scope the invocation to the dependency? How can I force a bin script to package its own npm dependency and rely on that? Is nested scripts in nested dependency package.json the best way, or is there a better more canonical solution?
I ended up being able to get the behaviour I want by changing the last line of bin/foo to:
npm explore #myprivate/repo npm run example
This does feel a little bit happy (I'm referencing the repo using npm explore from within itself), but it does get the job done. Would love to hear of a better solution

Testing via npm command line

I have two types of test suites - normal and coverage.
At present, I am allowing one of them via npm test and one of them via npm start:
"scripts": {
"test": "node scripts/run-truffle-tests.js",
"start": "node scripts/run-sol-coverage.js"
}
I have a feeling that npm start was not originally designated for this purpose.
Is there a better way to implement this?
I was thinking of passing an argument to npm test, but I'm not sure that npm would pass it on to the script which it is set to invoke.
Add more scripts.
I usually have the tests for actual, full, single run unit tests to work with CI and other scripts for variations:
{
"scripts": {
"test": "node scripts/run-truffle-tests.js && npm run test:coverage",
"test:continuous": "karma start some.config --run-continuous",
"test:coverage": "node scripts/run-sol-coverage.js"
"start": "node index.js"
}
}
You can also chain commands with && which will cause the script to be run in sequence and the "total" error code will propagate. In other words, using the test I have above, will run both the unit test and the coverage test. If either of them return a non-zero exit code, npm will consider the whole test process to have failed.
Bear in mind that for custom scripts not named exactly start and test as well as the other designated scripts found in the docs here: npm#scripts, must be run with
npm run scriptname
instead of just
npm scriptname
So in my above example, you would test coverage with:
npm run test:coverage
Also, the : is just a convention. As far as I know it's not special.
Additionally, you can
pass [argument] on to the script which it is set to invoke
Whenever use use npm test, what is basically happening is that npm runs whatever String value is set in the package.json's scripts.test as a process, as though you had typed that String into the shell yourself. It then looks at the return code and if it's 0, it reports as everything being ok; if it's non-zero, it prints an error.

'standard' is not recognized as an internal or external command

I want to integrate some kind of code linting for node.js in webstorm so I installed standard to my node.js project using:
npm instal standard --save-dev
It was installed and listed in the "devDependencies" section of package.json but when I run the command:
standard
in the console I get
'standard' is not recognized as an internal or external command
if you want to use it locally you have to include it in you scripts first in package.json
"scripts": {
"standard": "standard",
"standard::fix": "standard --fix"
}
and use npm run standard to run it. or if you are using yarn type yarn standard
The scripts are in node_modules\.bin.
So, either:
Add this to PATH before running standard, e.g.:
set PATH=%PATH%;node_modules\.bin
Run it in using node_modules\.bin\standard
Use #tarek's approach using package.json: https://stackoverflow.com/a/49026837/122441
"scripts": {
"test": "standard middlewares/validations.js"
}
Add above lines in package.json.
Here middlewares/validations.js is the path of the file to check.
Run -> npm test
If this file have any error you will get.

OS independent access to variables in package.json

To access a variable in npm scripts you would do something like this in your package.json:
"scripts": {
"preinstall": "echo ${npm_package_name}"
}
The problem is that works only in Unix, not Windows, where you have to use %npm_package_name%.
Is there a way to do this OS independent? It will be good if npm could do such a variable expansion, before invoking the command.
To make it cross-platform, use cross-var:
"scripts": {
"preinstall": "cross-var echo ${npm_package_name}"
}
There's no known way to do this that's OS independent.
A good workaround is to execute the command within a node script:
First, change the preinstall command to execute a node script:
"scripts": {
"preinstall": "node nameEcho.js"
}
Then you define the command in the nameEcho.js file:
// require the package.json file
var pjson = require('./package.json');
// echo the package's name
console.log(pjson.name);

Resources