nodemon : Passing arguments to the executable when using as a required module - node.js

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");
});

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

Run node shebang script from an Azure Pipeline step

Is it possible to call a node shebang script from an Azure Pipeline step?
I have a node shebang along these lines but I do not know what is involved in calling this from a pipeline step:
const processUrl = async (url, reportDir) => {
console.log(chalk.yellow(`about to run lighthouse tests against ${url}`));
try {
await runCmd('docker',
[
'run',
'--rm',
'-it',
'-v',
`${reportDir}:/home/chrome/reports`,
'-v',
`${path.join(process.cwd(), 'lighthouse')}:/home/chrome/reports/config`,
'femtopixel/google-lighthouse',
url.replace("localhost", "host.docker.internal"),
'--config-path',
'./config/lighthouse-config.js',
'--output',
'html',
'--output',
'json'
])
} catch(err) {
console.error(err);
}
}
You need to add the shebang character sequence in the top of the file:
#!/usr/bin/env node
Now add a Bash task and run the file with the node command.
If you want to ensure that Node is installed you can use the task Node.js tool installer task:
- task: NodeTool#0
inputs:
versionSpec: 8.x
For example, the file test.js is:
#!/usr/bin/env node
const [,, ...args] = process.argv
console.log(`Hi ${args}`)
My Bash script is:
- bash: 'node test.js shayki'
The result is:

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 }

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' ]);
};

Run Sequelize migration after deployment to App Engine

I have create a sample project for myself to try Node.js with Sequelize on Google App Engine.
I can run the project locally and it works fine, however when I deploy it to App Engine gcloud app deploy
I get the following error:
{
name: "SequelizeDatabaseError",
message: "ER_NO_SUCH_TABLE: Table 'sql8175762.Likes' doesn't exist",
parent: {
code: "ER_NO_SUCH_TABLE",
errno: 1146,
sqlState: "42S02",
index: 0,
sql: "SELECT `id`, `code`, `likes`, `createdAt`, `updatedAt` FROM `Likes` AS `Likes`;"
},
original: {
code: "ER_NO_SUCH_TABLE",
errno: 1146,
sqlState: "42S02",
index: 0,
sql: "SELECT `id`, `code`, `likes`, `createdAt`, `updatedAt` FROM `Likes` AS `Likes`;"
},
sql: "SELECT `id`, `code`, `likes`, `createdAt`, `updatedAt` FROM `Likes` AS `Likes`;"
}
Thats because the Sequelize migration doesnt run however I do have it specified in npm start command:
"scripts": {
"deploy": "gcloud app deploy",
"start": "npm install & sequelize db:migrate & NODE_ENV=production node ./bin/www"
},
I have never used app engine for node deployment and I am not even sure if the steps I am talking are correct to deploy, migrate and run the app.
Does anyone have any tips regarding this?
I had the same experience, the problem is that for some reasons you have to add tableName and freezeTableName: true property in the defining model. for instance:
'use strict';
module.exports = (sequelize, DataTypes) => {
const File = sequelize.define('File', {
name: DataTypes.STRING,
courseId: DataTypes.INTEGER
}, {
freezeTableName: true,
tableName: 'files'
});
File.associate = function(models) {
// associations can be defined here
};
return File;
};
Im a little late to this question, but in case others are looking, it's worth noting that the example script shown uses & between the commands.
This will background each command and immediately run the next, so there's a good chance that both npm install and sequelize db:migrate are still running when node launches.
If you're on a unix system (Mac/Linux) You can test this locally by creating a file called ./test.sh containing
#!/bin/sh
echo "Starting long process ..."
sleep 5
echo "Long process done"
and then from the command line running
chmod +x test.sh
./test.sh & echo "Running second process"
Changing the commands to && should fix this, ie:
npm install && sequelize db:migrate && NODE_ENV=production node ./bin/www
I don't know your setup, but do you have sequelize-cli package dependency, also have you tried adding a .sequelizerc file in your root directory and add the paths for your config, migration and models? Example:
var path = require('path');
module.exports = {
'config': path.resolve('./', 'config/config.js'),
'migrations-path': path.resolve('./', 'src/server/migrations'),
'seeders-path': path.resolve('./', 'src/server/seeders'),
'models-path': path.resolve('./', 'src/server/models')
};
you should use && instead of & in your start command.
& means to run the command at background.
&& means "logic and" so that the shell will run the command one by one and wait for each returned code.

Resources