Node and NPM Tips and Tricks

Little Node and NPM secrets I learnt along the way

Tip: if you do not have Node installed on your machine, watch this video where I install Node on a Mac, and then install and open Cypress.

Install and test

You can install NPM dependencies and run tests with a single command:

1
2
3
4
$ npm it
# is equivalent to
$ npm install
$ npm test

If you use the package-lock.json file:

1
2
3
4
$ npm cit
# is equivalent to
$ npm ci
$ npm test

See available script commands

If the package.json has "scripts" commands like these

1
2
3
4
5
6
7
{
"scripts": {
"test": "...",
"start": "...",
"lint": "..."
}
}

You can list them all using

1
$ npm run

Run the command in a different folder

You can use the option --prefix <path/to/folder> to run NPM command in a particular folder. It works like a cross-platform cd <path/to/folder>; npm ... combination.

Let's say we are in a larger project, and the server we want to launch is in its own subfolder

1
2
3
4
5
6
app/
package.json # top-level project (optional)
sub/
folder/
package.json
index.js

Let's say the sub/folder/package.json has a "start" script

sub/folder/package.json
1
2
3
4
5
{
"scripts": {
"start": "node ."
}
}

Then we can install the dependencies and launch the app in the sub/folder all from the root app/ folder:

1
2
3
4
5
app/ $ npm --prefix sub/folder install
app/ $ npm --prefix sub/folder start
...
# after each command, the current directory is still app/
app/ $

Suppress extra logging output

By default, npm run <script name> prints extra text

1
2
3
4
5
$ npm run print-me

> [email protected] print-me
...
(output from print-me)

You can suppress it using the --silent flag (which hides all extra output, including STDERR)

1
2
$ npm run print-me --silent
(output from print-me)

Keep NPM dependencies up-to-date

  • using an external service like my favorite Renovate is my preferred way of keeping NPM dependencies up-to-date, read my Renovate blog posts
  • using local tool next-update gives you stats and runs the tests when upgrading each module to ensure the update does not break the project

Control the NPM cache

By default NPM downloads the modules to install into ~/.npm folder (and a similar user folder on Windows). You can change the cache folder using an environment variable npm_config_cache. You can also change it at run-time by providing --cache <path/to/folder> argument:

1
2
3
# install NPM dependencies using a local folder ".npm" to
# cache, prefer already found modules from the cache
$ npm i --cache .npm --prefer-offline

Run a node command or expression

1
$ node -e 'console.log("Hello there")'

Print the result of an expression

You can avoid console.log by using -p flag that automatically prints the result of the expression

1
2
3
4
5
$ node -e 'console.log(42)'
42
# is the same as
$ node -p '42'
42

Generate random string

1
2
$ node -p 'crypto.randomBytes(4).toString("hex")'
657bfb6c

Pseudo-random using `Math.random()

1
Math.random().toString().slice(2, 10)

See NPM environment variables

When NPM command like npm run ... executes, it puts all NPM config values into the process.env object. To see all variables set, use

1
$ npm run env

There will be variables prefixed with npm_config_, npm_package_scripts_, npm_config_global_, etc.

Open NPM package homepage in the browser

1
2
3
$ npm home <npm package name>
# example
$ npm home cypress

Delete files

To delete files the same way, no matter the operating system, use del-cli as I show in bahmutov/test-del-cli repo. For example, using NPX you could do:

1
$ npx del-cli 'cypress/screenshots/*'

Make sure to pass the wildcards using quotes to let the del-cli find the files.

Note: if there are no files matching the pattern, del-cli exits with code 0

Run NPX command from specific package

Use the NPM package and find the alias inside:

1
2
3
4
5
$ npx available-versions cypress-grep
npx: installed 261 in 10.531s
cypress-grep from git+https://github.com/bahmutov/cypress-grep.git
...
prints list of published versions for package "cypress-grep"

Specify the package name and the alias name to run:

1
2
# npx -p <package name> <bin alias name> <arguments...>
$ npx -p dependency-version-badge update-badge cypress

Run different NPM scripts depending on the platform

It is very annoying to have cross-OS differences, so the package run-script-os nicely helps with that. Example of doing a different test command:

package.json
1
2
3
4
5
6
7
8
{
"scripts": {
"test": "run-script-os",
"test:win32": "echo 'del whatever you want in Windows 32/64'",
"test:darwin:linux": "echo 'You can combine OS tags and rm all the things!'",
"test:default": "echo 'This will run on any platform that does not have its own script'"
}
}

The user only needs to execute npm test and an appropriate script will run depending on the platform.

Link local module using NPM

  • in the local package (for example called MyModule) run npm link
  • go into the project and run npm link MyModule

The node_modules/MyModule should be a link to the local package folder.

To remove the link, reverse the steps

1
2
3
4
# in the project
$ npm unlink --no-save MyModule`
# in the MyModule
$ npm unlink

Link local module using Yarn

If you are developing an NPM module and want to consume it in another local project, use Yarn link.

  • in the package you want share locally execute yarn link, for example in MyModule
1
/MyModule: yarn link
  • in all projects that use MyModule execute yarn link MyModule

Here is the result of linking mock-in-bundle in the current project. The node_modules/mock-in-bundle is a link to the external folder.

Linked local package

To unlink packages:

  • in all projects execute yarn unlink MyModule
  • in the MyModule package itself execute yarn unlink

Extra tools

Here are some useful tools I use every day:

  • npm-quick-run lets you run NPM scripts without typing the full script name.
  • available-versions fetches the new versions for the given NPM package name and shows them in a nice console table.
  • as-a runs a given command, including NPM scripts with additional settings from the secrets file injected as environment variables.
  • bin-up Finds an installed tool in node_modules/.bin folders from current up to the git root.
  • bahmutov/npm-install is my GitHub action for simple NPM installs (with caching) when using GitHub Actions.

Deprecate a released version

If you publish a new package version "x.y.z" by mistake, and want to deprecate it:

1
$ npm deprecate -f '[email protected]' "this version has been deprecated"

You probably want to tag another version with the latest tag

1
$ npm dist-tag add [email protected] latest

Find issues with dependencies

You can find issues with your dependencies by running npm audit --report command. Often it is too strict, since it also checks the development dependencies. Since my users will only install my NPM package plus its production dependencies, I use npm audit --report --omit dev command.

My NPM blog posts

Related posts