Skip to content

Instantly share code, notes, and snippets.

@khalidx
Last active April 22, 2024 20:12
Show Gist options
  • Save khalidx/70f14efa145da4e8d6c4ffb9cb9911bb to your computer and use it in GitHub Desktop.
Save khalidx/70f14efa145da4e8d6c4ffb9cb9911bb to your computer and use it in GitHub Desktop.
Fixing the issue with globstar paths (**/*) not working when running an npm script.

🚧 Issue Description

If you've ever run a script like npm run test from your package.json:

{
  "scripts": {
    "test": "node --test src/**/*.test.js"
  }
}

You'll notice we are using a globstar here src/**/*.test.js.

The thing is, on Linux, npm run runs scripts with sh by default.

By default, sh doesn't support globstar paths like **/*. So you'll notice that it'll only find files one directory deep, and will treat src/**/*.test.js as if you only wrote src/*/*.test.js.

This is a major pitfall that can easily go by undetected. For example, imagine your CI skipping 90% of your tests since it was looking at only some of the directories!

✅ Resolution Steps

⚠️ NOTE: This was only tested on Linux, and was not tested on Windows or Mac.

To fix this, figure out how to enable globstar in your shell. Or do what I did and just update npm to use zsh as the default shell for running scripts.

Unlike sh, zsh understands and expands globstar paths by default.

Here's how to do that:

  1. First run npm config ls -l | grep shell to see what config you have. It'll probably say:
script-shell = null
shell = "/bin/bash"
  1. Now, run npm config set script-shell=zsh to update the script-shell option to use zsh.

  2. Confirm that the update worked. Run npm config ls -l | grep shell. It'll probably say:

; script-shell = null ; overridden by user
shell = "/bin/bash"
script-shell = "zsh"
  1. Now, try using globstar paths again in your scripts. All the matching files should be discovered now by the shell (even several subdirectories deep).

You're all set! 😌

The problem now is... remembering to do this everywhere you use npm. 😢

(GitHub Codespaces, other laptop, work computer..................)

By the way, many tools that you would use within npm run scripts, like mocha, support quoting the globstar in the script, like 'src/**/*.test.js', in which case they will perform the globstar matching for you, not relying on the shell you are using. This is a great solution! Use this wherever possible.

Unfortunately, some tools don't support this yet, like the native Node.js v20 test runner node --test. When Node.js supports this, like node --test 'src/**/*.test.js', I won't really need this hack anymore!

@peterc
Copy link

peterc commented Feb 8, 2024

Interesting! So I ran some tests and sh aliases to bash on my Linux system. Bash doesn't support globstars by default but in any modern version you can enable support with shopt -s globstar which resolves this problem. This may be a better solution since it doesn't introduce any other potential changes that might be experienced moving to another shell.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment