How to print out multi-line message from npm script - node.js

Is it possible to print out a multi-line message from an npm script?
My team has an alternative script that needs to run in place of npm publish.
So instead of running npm publish from the terminal, we should be running npm run publish:lib. But, some team members forget about the alternative script and end up just running npm publish.
So what I've done so far is added this to my package.json:
"scripts": {
"postpublish": "node -e \"console.log('Did you mean npm run publish:lib?')\"",
}
That way when they do run npm publish, they'll be reminded about the alternative script. However, I'm not satisfied with it because it's not very noticible, and also the words console.log get's printed out, which is kind of ugly.
My goal is to have something printed out that looks like this:

The solution I ended up using was the following:
package.json
"scripts": {
"postpublish": "node publishWarning.js"
}
publishWarning.js
console.log('***************************************')
console.log('***************************************')
console.log('** Did you mean npm run publish:lib? **')
console.log('***************************************')
console.log('***************************************')

Related

What is the difference between npm start and http-server?

I am a beginner in web development. These two confuse me. If they both open up a page in localhost then why do I need to install http-server instead of just using npm start?
npm start runs whatever command is specified in the "start" script in your package.json. From the npm docs:
This runs an arbitrary command specified in the package's "start" property of its "scripts" object. If no "start" property is specified on the "scripts" object, it will run node server.js.
https://docs.npmjs.com/cli/v6/commands/npm-start
So if your package.json contains the following:
{
"scripts": {
"start": "echo Hello"
}
}
Then running npm start will print "Hello". The npm start script is not an executable itself; it just runs whatever is specified in your package.json.
http-server on the other hand is a specific executable that starts an HTTP server. It may refer to the http-server npm package, or a different script with that name available in your command line interface.
npm start is a convention often used by other tools, e.g. testing or continuous integration, to "start up" your app regardless of what technology it is using. A common set up would be to specify the specific startup script in your "start" script:
{
"scripts": {
"start": "http-server"
}
}
While that makes npm start and http-server do the same thing in your project directory, other tools will rely on npm start since otherwise they wouldn't know that you wanted to use http-server as your startup script.
http-server is an HTTP server written in JavaScript for Node.js.
npm start runs the start script specified in package.json. It might run a web server (which might be written using http-server) and open a browser to it. It might do something else. It's entirely configurable.

Confusion with npm scripts

I am trying to figure out how the https://github.com/fastify/fastify-example-twitter/blob/master/package.json works.
Specifically, it has a script entry as: "start": "fastify index.js".
However, there is no requirement to install fastify globally. Nonetheless, npm start is working fine. It does start fastify, while doing it from the shell results in: -bash: fastify: command not found
What is happening when npm start is invoked? Why I cannot run this from the command line, while npm runs this script command just fine.
If your dependency appears in an npm script command, the executable is added to your path.
From the npm scripts documentation:
If you depend on modules that define executable scripts, like test
suites, then those executables will be added to the PATH for executing
the scripts. So, if your package.json has this:
{
"name" : "foo" ,
"dependencies" : {
"bar" : "0.1.x"
} ,
"scripts": {
"start" : "bar ./test"
}
}
then you could run npm start to execute the bar script, which is
exported into the node_modules/.bin directory on npm install.
fastify is listed as a dependency, and as such can be ran as an npm script. The same goes for mocha, standard, and snazzy. None of them need to be globally installed, but are ran via their npm scripts.

npm run does nothing

I've been working with Node.js/npm for a while, but I never used npm scripts. I was quite surprised to find that I can't get them to work at all on my Windows/Cygwin system. With a package.json like this ...
{
"name": "demo",
"scripts": {
"env": "env",
"hello": "echo Hello!",
"crap": "I am complete nonsense."
}
}
... all three npm run commands do nothing. npm run crap executes and returns immediately with an OK status (I tested with the -dd parameter); npm run doesntexist throws the expected error. Testing without Cygwin on the regular Windows shell made no difference.
I finally found out myself. There is an npm setting with which you can stop all npm scripts from running. For some reason, my userconfig file ~/.npmrc contained the setting ignore-scripts = true. If you run into this problem, check npm config list.

Can I pass a parameter to the first command in a multipart npm script?

I want to have an npm task that looks something like
"deploy": "npm version; echo \"Do other stuff\""
But I need to get the version argument to npm version for it to do anything. Is that possible?
The only thing I have working now is to move the following commands into a postdeploy task, which then works if I run $ npm run deploy minor, but I want to know if what I describe above is possible.

How to suppress output when running npm scripts

I have decided to experiment with npm scripts as a build tool and so far I like it. One issue I'd like to solve is when running a script to run jshint when something doesn't pass linting I get a ton of "npm ERR!" lines. I would like to suppress these as the output from the linter is more meaningful.
Is there a good way to set this globally and is there a way to set it for each script run?
All scripts:
You can fix this by suppressing the output of npm overall, by setting the log level to silent in a couple ways:
On each npm run invocation:
npm run --silent <your-script>
Or by creating a .npmrc file (this file can be either in your project directory -local- or your home folder -global-) with the following:
loglevel=silent
Resources:
npm log level config: https://docs.npmjs.com/misc/config#loglevel
npmrc: https://docs.npmjs.com/misc/config#loglevel
Each script, individually:
A simple trick I've used to get around this issue on certain scripts like linting is to append || true at the end of such scripts. This will work without any npm config changes.
This will ensure that the script will always exit with a 0 status. This tricks npm into thinking the script succeed, hence hiding the ERR messages. If you want to be more explicit, you can append || exit 0 instead and it should achieve the same result.
{
"scripts": {
"lint": "jshint || true",
}
}
You should be able to use both the --quiet and --silent options, as in
npm install --quiet
--quiet will show stderr and warnings, --silent should suppress nearly everything
You can also send stdout/stderr to /dev/null, like so:
npm install > '/dev/null' 2>&1
or less versbose
npm install &> '/dev/null'
npm install --quiet --no-progress
Will keep warnings and errors, and suppress the ADHD progress bar on terminals that support it.
for an individual script that you want to keep silent without having to add --silent each time, you can make a new script that calls your previous one and adds --silent.
My example scripts in package.json:
"dev-loud": "npm run build && nodemon -r dotenv/config dist/index.js",
"dev": "npm run dev-loud --silent"
You can do this inside your script by removing the event listeners
#!/usr/bin/env node
process.removeAllListeners('warning');
// Do your thang without triggering warnings

Resources