Feb 6, 2020

How to check npm scripts in current directory

As a front-end engineer, I spend a lot of time jumping in-between JavaScript projects. Often times I want to run a command from those projects to start watchmode or spin up a service.

The commands that I want to use are in the package.json under "scripts". When I haven’t memorized the common commands, I need to either open the file in my editor or use a Unix utility like cat.

# In my editor
code package.json

# In the terminal
cat package.json

Both of these commands work, but they are slow. package.json files can be massive, including dozens of dependencies, dev depenendencies, and other fields. To find the scripts, I need to sort through the cruft to find the information that I want. This isn’t very efficient.

Instead, I wrote a short bash scripts to quickly do the work for me. Here is the code in all of its glory:

#!/bin/bash

if [[ -f "package.json" ]]; then
node -pe "JSON.parse(require('fs').readFileSync('package.json').toString()).scripts"
else
echo "There is no `package.json` in this directory"
fi

First, I let the computer know to run this file with bash. Then I set up an if block: if there is a package.json file in this directory, then run the following code; if not, then print a “can’t find it” message.

The code to run, inspired by a StackOverflow comment, is a node process with two flags:

  • -e tells node to evaluate the script that you pass
  • -p tells node to print the results to the console

Within the script, I am using JSON to parse the results of a fs.readFileSync() of the package.json, then diving down to the scripts key.

I set it up by running chmod with two flags on the file in a scripts/ directory:

chmod u+x ~/scripts/npm-scripts

Then I could resource my terminal and run the command with npm-scripts. Bish bash bosh.

Everything worked fine, but I wanted an easier way to share my script with others. The chmod command and flags are hard to remember, so it would be easier if the script could be compressed into a one-liner that could be aliased in their ~/.bash_profile.

To do that, I removed all the new lines and added semicolons to separate the statements. The alias needed to be wrapped in quotes, so I escaped all the double quotes within the script.

Now I had a handy alias to share:

alias ns="if [[ -f \"package.json\" ]]; then node -pe \"JSON.parse(require('fs').readFileSync('package.json').toString()).scripts\"; else echo \"There is no package.json in this directory\"; fi"

Overall, I’m pretty happy with this utility. Going forward, I would like to extend it so that you can lookup and key on package.json by passing an argument.

1 Timothy 2:5 (SDG)

An illustration of Sean McPherson's face

My name is Sean McPherson, and I'm a software engineer and educator living in Pittsburgh, PA.

I write about React, JavaScript, accessibility, user experience, and occasionally some other topics.