26

I would like to have automatically invoked "nvm use" when I run "npm start". So I come up with this solution:

package.json file

"scripts": {
  "prestart": "sh test.sh",
  "start": "nodemon index.js"
}

.nvmrc file

4

test.sh file

#!/bin/bash

if [ -d ~/.nvm ]
  then
    source ~/.nvm/nvm.sh

    nvm use
fi

This works and switches between nvm versions console output is:

> sh test.sh

Found '/my-user-path/.nvmrc' with version <4>
Now using node v4.2.2 (npm v2.14.7)

> app@1.0.0 start /app-path/
> nodemon index.js

But when I call form index.js "console.log(process.versions);" nvm script is executed probably in different process so output is:

{ 
  http_parser: '2.6.0',
  node: '5.1.0',
  v8: '4.6.85.31',
  uv: '1.7.5',
  zlib: '1.2.8',
  ares: '1.10.1-DEV',
  icu: '56.1',
  modules: '47',
  openssl: '1.0.2d' 
}

Any suggestions on how to deal with this in a proper way?

Thanks

Afsanefda
  • 3,069
  • 6
  • 36
  • 76
Carl Moravec
  • 261
  • 1
  • 3
  • 4

3 Answers3

28

Generally on a Mac, the nvm.sh file is located in your home path. Use the $HOME variable if you have multiple Mac users working on the code.

"scripts": {
    "prestart": "source $HOME/.nvm/nvm.sh; nvm use"
}

I would've added this as a comment to the above response, but I'm not allowed :(

Ribbo
  • 399
  • 3
  • 11
13

Your package.json could look like

"scripts": {
    "start": "source /whereever/located/nvm.sh; nvm use; nodemon index.js"
}

To explain. The "start" line is a single shell instance. So you have to have nvm initialize the PATH in that shell instance. Also, nvm is a shell function not an executable shell script. The nvm function lives in the shell instance, and is created by sourcing the nvm.sh file.

Sorry for the edits cuz I didn't test my first two.

blong
  • 2,815
  • 8
  • 44
  • 110
LLeo
  • 131
  • 4
  • Thank you @LLeo. This worked best for me because I was able to create my own script that wouldn't affect my team members since I don't know who has nvm and if it's installed in the same location as everyone else. I didn't test it but by the name, prestart would affect all scripts which is not wanted in my case. – Devin Ledesma Dec 10 '20 at 19:46
  • 1
    I did have a question about your answer though. Is using a semicolon equivalent to using double ampersand? `; => &&` I tried both ways and they worked. Just was hoping to understand the differences, if there are any other than aesthetics – Devin Ledesma Dec 10 '20 at 19:48
  • 4
    Semicolon is just a command separator in shell. "&&" executes the rest of the line only if the command on the left return "true" which is exit code 0 (non-zero if false). – LLeo Dec 12 '20 at 02:13
  • 1
    Thank you @LLeo. Once again I appreciate your great answers :) – Devin Ledesma Dec 16 '20 at 02:19
2

for mac eg :

"scripts": {
    "dev": "source $HOME/.nvm/nvm.sh; nvm use;nvm use v14.17.5 && cross-env ENV_TYPE=localhost umi dev"
  },