How can NPM scripts use my current working directory (when in nested subfolder)

16.4k views Asked by At

It's good that I can run NPM scripts not only from the project root but also from the subfolders. However, with constraint that it can't tell my current working path ($PWD).

Let's say there's a command like this:

"scripts": {
  ...
  "pwd": "echo $PWD"
}

If I run npm run pwd within a subfolder of the project root (e.g, $PROJECT_ROOT/src/nested/dir), instead of printing out my current path $PROJECT_ROOT/src/nested/dir, it always gives $PROJECT_ROOT back. Are there any way to tell NPM scripts to use my current working directory instead of resolving to where package.json resides?

Basically I want to pull a Yeoman generator into an existing project and use it through NPM scripts so that everyone can use the shared knowledge (e.g, npm run generator) instead of learning anything Yeoman specific (e.g npm i yo -g; yo generator). As the generator generates files based on current working path, while NPM scripts always resolves to the project root, I can't use the generator where it intend to be used.

3

There are 3 answers

1
Allen On

One known solution is through ENV variable injection.

For example:

Define scripts in package.json:

"pwd": "cd $VAR && echo $PWD"

Call it from anywhere sub directories:

VAR=$(pwd) npm run pwd

However, this looks really ugly, are there any cleaner/better solutions?

0
Marcel Stör On

If you want your script to use different behavior based on what subdirectory you’re in, you can use the INIT_CWD environment variable, which holds the full path you were in when you ran npm run.

Source: https://docs.npmjs.com/cli/run-script

Use it like so:

"scripts": {
    "start": "live-server $INIT_CWD/somedir --port=8080 --no-browser"
}

Update 2019-11-19

$INIT_CWD only works on *nix-like platforms. Windows would need %INIT_CWD%. Kind of disappointing that Node.js doesn't abstract this for us. Solution: use cross-env-shell live-server $INIT_CWD/somedir.... -> https://www.npmjs.com/package/cross-env

0
Sortiz On

With node 8+ you can automate the ENV variable injection.

1.- In $HOME/.node_modules/ (a default node search path) create a file mystart with

process.env.ORIGPWD = process.env.PWD

2.- Then in your $HOME/.bashrc tell node to load mystart every time

export NODE_OPTIONS="-r mystart"

3.- Use $ORIGPWD in your scripts. That works for npm, yarn and others.