Accessing command line arguments to npm script - npm-scripts

This is what i have in my package.json file, in the scripts section:
{
"version": "0.0.1",
},
"scripts": {
"dev-wip": "environment=DEV --tags=#wip"
}
This is how my command line:
npm run dev-wip
I have no problem accessing variables in the package.json file, by doing this:
var pjson = require('../../../package.json');
console.log('version - ' + pjson.version);
I want to be able to access the environment parameter (print the value, for example) that i got from the command line.

I found the solution.
Using this will give my the value of the "environment" parameter (which is "DEV" in my example).
process.env.environment

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 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.

How can I reference package version in npm script?

I want to reference my package version in a npm script so I can show current version in the app.
Something like
{
"name": "bla",
"version": "1.0.0",
"author": "bla bla",
"scripts": {
"build": "node VERSION=<<package.version>> build/build.js"
}
}
Is there a way to do this?
1) Referencing package version in npm-scripts.
In npm-script's you can reference the version using the variable npm_package_version. For example:
Using a bash shell (E.g. Linux, macOS):
{
...
"version": "1.0.0",
"scripts": {
"build": "echo $npm_package_version"
}
}
Note the $ prefix
Using Windows (E.g. cmd.exe, Powershell):
{
...
"version": "1.0.0",
"scripts": {
"build": "echo %npm_package_version%"
}
}
Note the % prefix and suffix
Cross platform
To utilize one syntax cross-platform check out the package cross-var
2) Referencing package version in node script.
The package version can also be referenced in your a app/node script (i.e. build.js) as follows:
const VERSION = process.env.npm_package_version;
console.log(VERSION); // --> 1.0.0
3) Replacing a placeholder string in a .js file with package version.
Another way to achieve this is to specify a placeholder text string within your JavaScript file. Lets say we have a file named build.js and within that file we have a variable named VERSION declared as follows:
// build.js
const VERSION = '#VERSION#'
As you can see, the placeholder text string is #VERSION#.
You can then install and utilize the package called replace in an npm-script as follows:
{
...
"version": "1.0.0",
"scripts": {
"add-version": "replace -s \"#VERSION#\" $npm_package_version build/build.js"
}
}
Running npm run add-version will replace the instance of #VERSION# with the package version (i.e. 1.0.0), in the file named build.js. This solution will hard-code the npm package version into the resultant file.
Note: The to string in the add-version script (above) currently uses the $ prefix (i.e. $npm_package_version) to access the variable, so this will only run successfully on a bash shell. However, for cross-platform usage you'll need to use cross-var as explained in section one (above). In which case the add-version script can be defined as follows:
{
...
"version": "1.0.0",
"scripts": {
"add-version": "cross-var replace -s \"#VERSION#\" $npm_package_version build/build.js"
}
}

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

Cross platform NPM start script

I'm building out an Electron app that will be developed by folks on both Windows and OS X. I'd like to create a cross-platform start script. So far, I've had exactly zero luck getting something that works. The issue, I think, is that I need to set the NODE_ENV environment variable and the syntax is slightly different.
I'm hoping there's a way that I just haven't found yet. My current scripts section follows:
"scripts": {
"start:osx": "NODE_ENV=development electron ./app/",
"start:win": "set NODE_ENV=development && electron ./app/"
}
I'd really like to create a single "start" script and eliminate the platform-specific variants. Is it possible?
Environment variables are a problem in Windows.
As stated Domenic Denicola (one of the main contributors to npm) :
This is not npm's job. You can run custom Node scripts to set environment variables using process.env if you'd like, or use something that isn't environment variables (like JSON).
...
You can write custom scripts to work around connect's limitations, e.g. in your tests modify process.env.
(Reference : this issue)
So we'll manage through a JS script (Solution inspired on this commit) :
Create a exec.js file in a scripts directory
Copy the following code in exec.js :
var exec = require('child_process').exec;
var command_line = 'electron ./app/';
var environ = (!process.argv[2].indexOf('development')) ? 'development' : 'production';
if(process.platform === 'win32') {
// tricks : https://github.com/remy/nodemon/issues/184#issuecomment-87378478 (Just don't add the space after the NODE_ENV variable, just straight to &&:)
command_line = 'set NODE_ENV=' + environ + '&& ' + command_line;
} else {
command_line = 'NODE_ENV=' + environ + ' ' + command_line;
}
var command = exec(command_line);
command.stdout.on('data', function(data) {
process.stdout.write(data);
});
command.stderr.on('data', function(data) {
process.stderr.write(data);
});
command.on('error', function(err) {
process.stderr.write(err);
});
Update your package.json :
"scripts": {
"start": "node scripts/exec.js development",
}
Run npm script : npm run start
Edit 05.04.2016
There is a very useful npm package that allows manages this problem : cross-env. Run commands that set environment variables across platforms