0

This question already has an answer here:

On my Ubuntu machine, I have a lot of javascript / typescript projects.

Each of npm's binary might have a global installation, like tsc at

~/.nvm/versions/node/v7.10.0/bin/tsc
$ tsc -v
Version 2.4.2

and it each project will define its own binary at:

~/src/project/node_modules/.bin/tsc 
$ cd ~/src/project && ./node_modules/.bin/tsc -v
Version 2.3.4   

I have a lot of nodejs / typescript projects, and whenever I call a command, e.g. tsc, I always want to run the project's as the first choice, and only then fallback to the global installation.

I know that npm scripts will always call the command from ./node_modules/.bin/ and hence setting up scripts like:

$ jq .scripts package.json 
{
  "test": "mocha --compilers js:babel-register --recursive tests/unit",
  "start": "node start.js",
  "start-dev": "nodemon start.js",
  "tslint": "tslint 'src/**/*.ts?(x)' --fix",
  "tsc": "tsc"
}

would suffice. I could then call:

> pink_elephant@1.0.0 tsc /home/philipp/myProject
> tsc "-v"

Version 2.3.4   

Yet not all my projects have these scripts defined, and I find handling the arguments via -- annoying.

So in order of making my life as a developer easier, I like to define my path in a way, that whenever I:

cd someProjectFolder

it looks for the existence of:

./node_modules/.bin/

and if it exists, add it to the path of the current shell.

How can I achieve this?

marked as duplicate by Gilles bash Aug 3 '17 at 22:54

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • are you really sure you want to do this? you'll end up with an enormous PATH and you'll never be sure which program of any given name you're about to run. I think this is a bad idea, so I'm not going to write an answer, only a pointer in the right direction: writing a function wrapper around cd would probably be your best bet here. You don't want this to happen every time you display the shell prompt, only when you enter a directory. hmmm....implementing this as a (i.e. a pushpath/poppath analog to pushd/popd) might be interesting and useful way to do this) – cas Aug 3 '17 at 13:28
  • @cas Yes, as currently I often run into the problem of running the global installation by mistake and I get tired of typing ./node_modules/.bin/. I understand the danger that some script kiddie might hijack the rm command in a npm package, yet that's what I have backups for. It's maybe something to keep in mind when writing the script, that it also lists the commands that are now registered. – k0pernikus Aug 3 '17 at 13:42
  • damn and now i notice i deleted a word. the missing word before the (i.e. is stack in case it's not obvious. re: listing paths, that's part of the reason i suggested a stack like pushd. the dirs command in bash allows you to view and manipulate the directory stack. so, write a pushpath function, a poppath function, a paths function, another function to parse your .scripts file and then a wrapper function around cd to change the PATH if/as required. – cas Aug 3 '17 at 13:47
  • btw, these need to be functions (or maybe aliases if they're simple enough). They can't be external scripts/programs because they have to manipulate the environment of your shell ($PATH variable. and whatever array var you use for the stack) - and a child can't change parent's env. – cas Aug 3 '17 at 13:49
  • If you're always in the top level of your project when you call stuff, you could simply add ./node_modules/.bin/ to your path. You could even cheat and add ../node_modules/.bin/ as well, but I don't know how many levels of directories you have in your projects. – Ulrich Schwarz Aug 3 '17 at 18:40

Browse other questions tagged or ask your own question.