Access command line argument in scripts of package.json - node.js

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 }

Related

Passing parameters from Jenkins CI to npm script

When I run Jenkins build, I would like to pass COMMIT_HASH and BRANCH_NAME to one of my javascript files: publish.js, so that I can remove hard-coded values for tags and consumerVersion.
Here is my code:
Jenkinsfile
stage('Publish Pacts') {
steps {
script {
sh 'npm run publish:pact -Dpact.consumer.version=${COMMIT_HASH} -Dpact.tag=${env.BRANCH_NAME}'
}
}
}
package.json
"scripts": {
"publish:pact": "node ./src/test/pact/publish.js"
}
./src/test/pact/publish.js
let publisher = require('#pact-foundation/pact-node');
let path = require('path');
let opts = {
providerBaseUrl: `http://localhost:${global.port}`,
pactFilesOrDirs: [path.resolve(process.cwd(), 'pacts')],
pactBroker: 'http://localhost:80',
tags: ["prod", "test"], // $BRANCH_NAME
consumerVersion: "2.0.0" // $COMMIT_HASH
};
publisher.publishPacts(opts).then(() => {
console.log("Pacts successfully published");
done()
});
Does anyone know how to do this?
You can pass cli arguments to your node script which end up in your process.argv.
Also npm passes on cli arguments via two dashes --.
To illustrate this consider this example:
Jenkinsfile
stage('Publish Pacts') {
steps {
script {
sh 'npm run publish:pact -- ${COMMIT_HASH} ${env.BRANCH_NAME}'
}
}
}
package.json
"scripts": {
"publish:pact": "node ./src/test/pact/publish.js"
}
publish.js
// process.argv[0] = path to node binary
// process.argv[1] = path to script
console.log('COMMIT_HASH:',process.argv[2]);
console.log('BRANCH_NAME:',process.argv[3]);
I left the cli flags out for simplicity.
Hope this helps

Is there a way to pass the cypress.io baseUrl env var into my package.json run scripts?

I want to be able to pass the baseUrl from the cypress.json file into the scripts of the package.json file for my cypress test project. Is this possible?
I have been looking at the cypress documentation and stack overflow but I cannot find a solution that does not require adding another script to do something like "get-base-url": "type cypress.json | jq -r .baseUrl" and pass this script as an argument into the relevant "test" script (see below)
cypress.json file
{
"baseUrl": "http://localhost:3000/",
//other key-value pairs
}
}
package.json scripts section
{
//other settings
"scripts": {
//other scripts
"test": "start-server-and-test website:dev http://localhost:3000 cy:run",
},
//other settings
}
I anticipated there would be an equivalent to Cypress.config().baseUrl, to get the value of the baseUrl in the json file.
Resulting in something similar to the following (sudo-code, doesnt work)
{
//other settings
"scripts": {
//other scripts
"test": "start-server-and-test website:dev ${baseUrl} cy:run",
},
//other settings
}
NB: I have not posted on Stack Overflow before, so I apologise if I have not given enough info and/or missed something in the rules.
scripts capability is limited. You need a small script to receive baseUrl from cypress.json and pass it into the start-server-and-test package
Let's say we create a script called start-server-and-test.js with the following code and put it under the scripts directory
const cypressConfig = require('../cypress.json') // line 1
const startServerAndTest = require('start-server-and-test') // line 2
const [startScript, testScript] = process.argv.slice(2) // line 3
startServerAndTest({ // line 4
start: `npm ${startScript}`,
url: cypressConfig.baseUrl,
test: `npm ${testScript}`,
})
Here is how we use it in package.json
{
"scripts": {
"test": "node scripts/start-server-and-test.js website:dev cy:run",
},
}
Short explanation:
Line 1: read cypress.json and assign to cypressConfig which you can access baseUrl later by cypressConfig.baseUrl
Line 3: retrieve arguments in the command-line which are ['website:dev', 'cy:run']
Line 4: Run the package with corresponding parameters
Just wanted to elaborate on Hung Tran's solution above for 2021:
/* eslint-disable #typescript-eslint/no-var-requires */
require("dotenv").config();
const startServerAndTest = require("start-server-and-test");
const [startScript, testScript] = process.argv.slice(2);
startServerAndTest.startAndTest({
services: [{ start: `npm run ${startScript}`, url: process.env.CYPRESS_BASE_URL }],
test: `npm run ${testScript}`,
});

How to execute npm script using grunt-run?

I have a npm task in my package.json file as follows to execute jest testing:
"scripts": {
"test-jest": "jest",
"jest-coverage": "jest --coverage"
},
"jest": {
"testEnvironment": "jsdom"
},
I want to execute this task npm run test-jest using grunt. I installed grunt-run for the same and added the run task, but how do I invoke this npm task there?
run: {
options: {
// Task-specific options go here.
},
your_target: {
cmd: 'node'
}
}
Configure your Gruntfile.js similar to the example shown in the docs.
Set the value for the cmd to npm.
Set run and test-jest in the args Array.
Gruntfile.js
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-run');
grunt.initConfig({
run: {
options: {
// ...
},
npm_test_jest: {
cmd: 'npm',
args: [
'run',
'test-jest',
'--silent'
]
}
}
});
grunt.registerTask('default', [ 'run:npm_test_jest' ]);
};
Running
Running $ grunt via your CLI using the configuration shown above will invoke the npm run test-jest command.
Note: Adding --silent (or it's shorthand equivalent -s) to the args Array simply helps avoids the additional npm log to the console.
EDIT:
Cross Platform
Using the grunt-run solution shown above failed on Windows OS when running via cmd.exe. The following error was thrown:
Error: spawn npm ENOENT Warning: non-zero exit code -4058 Use --force to continue.
For a cross-platform solution consider installing and utlizing grunt-shell to invoke the npm run test-jest instead.
npm i -D grunt-shell
Gruntfile.js
module.exports = function (grunt) {
require('load-grunt-tasks')(grunt); // <-- uses `load-grunt-tasks`
grunt.initConfig({
shell: {
npm_test_jest: {
command: 'npm run test-jest --silent',
}
}
});
grunt.registerTask('default', [ 'shell:npm_test_jest' ]);
};
Notes
grunt-shell requires load-grunt-tasks for loading the Task instead of the typical grunt.loadNpmTasks(...), so you'll need to install that too:
npm i -D load-grunt-tasks
For older version of Windows I had to install an older version of grunt-shell, namely version 1.3.0, so I recommend installing an earlier version.
npm i -D grunt-shell#1.3.0
EDIT 2
grunt-run does seem to work on Windows if you use the exec key instead of the cmd and args keys...
For cross platform purposes... I found it necessary to specify the command as a single string using the exec key as per the documentation that reads:
If you would like to specify your command as a single string, useful
for specifying multiple commands in one task, use the exec: key
Gruntfile.js
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-run');
grunt.initConfig({
run: {
options: {
// ...
},
npm_test_jest: {
exec: 'npm run test-jest --silent' // <-- use the exec key.
}
}
});
grunt.registerTask('default', [ 'run:npm_test_jest' ]);
};

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 () => {}

nodemon : Passing arguments to the executable when using as a required module

I'm trying to start a script with nodemon, using it as a required module, and I cannot pass arguments correctly.
For example, for
var args = [
process.argv[0], '--harmony',
'/path/to/script.js', '-i', 'logs'
];`
I'm expecting the script to be launched as :
node --harmony /path/to/script.js -i logs
But it doesn't work and all I can manage to get is
node --harmony /path/to/script.js -i logs /path/to/script.js
This is what I tried :
var app = require('nodemon')({
script: args[2],
exec: args.join(' ')
});
I know about execMap, but it's no good as I cannot pass arguments at the end anyway.
How can it be done?
Skimming through the source code, I found the args config options (undocumented...). It turns out to be what I needed.
var app = require('nodemon')({
exec: args.slice(0, 2),
script: args[2],
args: args.slice(3)
});
I recommend use gulp with nodemon
var argv = require('optimist').argv
gulp = require("gulp"),
nodemon = require("gulp-nodemon");
gulp.task("default", [], function(){
nodemon({
script: 'app.js',
ignore: ["public/*"],
env: {'NODE_ENV': 'development'},
args: ["--port="+argv.port],
exec: "node --harmony"
}).on("start");
});

Resources