James Munsch

In response to the suggestions of this post:

http://www.johnpapa.net/how-to-use-npm-global-without-sudo-on-osx/

John Papa's post is out of date IMO.

(also note this very post you are reading will be out of date in a few weeks 10/7/2015)

So why not (brew/apt-get/make install/yum/apt) node and npm?



Because Don't install nvm via brew, Don't install node via brew, Don't install npm via brew, Just source the nvm script, which the following one liner does auto-magically.


curl -o- https://raw.githubusercontent.com/creationix/nvm/MOSTCURRENTVERSIONHERE/install.sh | bash
  
(replacing the MOSTCURRENTVERSIONHERE) https://github.com/creationix/nvm

then nvm install 4, nvm install 0.12, nvm install 0.10, or nvm install iojs.

The reason being is that Mr. Papa suggests relocating everything to the home directory by hand ....... which it is good idea but, nvm does this, with the benefit of not having to re-source/link node and npm every time when switching between versions.

If brew and node/npm are already installed then brew uninstall them, because using the brew installer, or nodes installer, or npm's installer will place them all over the file system.

Did i mention out of date ... See: https://github.com/Homebrew/homebrew/blob/master/Library/Formula/nvm.rb#L14-L16

So more about brew and node and npm:


->  project2 git:(dev) $ brew --prefix npm
/usr/local/opt/node

->  project2 git:(dev) $ brew --prefix node
/usr/local/opt/node

->  project2 git:(dev) $ which node
/usr/local/bin/node

->  project2 git:(dev) $ which npm
/usr/local/bin/npm

So some linked files I see:


->  project2 git:(dev) $ ls -li /usr/local/bin/node
484447 lrwxr-xr-x  1 jmunsch  admin  30 Aug 17 11:24 /usr/local/bin/node -> ../Cellar/node/0.12.7/bin/node

->  project2 git:(dev) $ which npm
/usr/local/bin/npm

->  project2 git:(dev) $ ls -li /usr/local/bin/npm
487647 lrwxr-xr-x  1 jmunsch  admin  46 Aug 17 11:24 /usr/local/bin/npm -> /usr/local/lib/node_modules/npm/bin/npm-cli.js

  

And what about a global?



->  project2 git:(dev) $ which gulp                    
/usr/local/bin/gulp

->  project2 git:(dev) $ ls -li /usr/local/bin/gulp    
12691238 lrwxr-xr-x  1 jmunsch  admin  36 Oct  7 15:18 /usr/local/bin/gulp -> ../lib/node_modules/gulp/bin/gulp.js

->  project2 git:(dev) $ ls /usr/local/lib/node_modules
bower     grunt     grunt-cli gulp      nodemon   npm
  

Alright so brew just drops node into a cellar and links it, throws npm into node_modules and links it, and npm just links gulp. So updating any global npm packages will cause problems. What about breaking changes between npm and node? What about switching versions of node? (unlink, git magic things, brew formulas, more magic)

What about nvm?



->  project2 git:(dev) $ nvm use 4    
Now using node v4.1.1 (npm v2.14.4)

->  project2 git:(dev) $ which node
/Users/jmunsch/.nvm/versions/node/v4.1.1/bin/node

->  project2 git:(dev) $ ls -li /Users/jmunsch/.nvm/versions/node/v4.1.1/bin/node
9876271 -rwxr-xr-x  1 jmunsch  staff  22237980 Sep 22 19:25 /Users/jmunsch/.nvm/versions/node/v4.1.1/bin/node

->  project2 git:(dev) $ which npm
/Users/jmunsch/.nvm/versions/node/v4.1.1/bin/npm

So some linked files I see, BUT oh its in the same directory as the node version it pertains to:


->  project2 git:(dev) $ ls -li /Users/jmunsch/.nvm/versions/node/v4.1.1/bin/npm
9876272 lrwxr-xr-x  1 jmunsch  staff  38 Sep 22 19:26 /Users/jmunsch/.nvm/versions/node/v4.1.1/bin/npm -> ../lib/node_modules/npm/bin/npm-cli.js

->  project2 git:(dev) $ ls /Users/jmunsch/.nvm/versions/node/v4.1.1/lib/node_modules 
grunt-cli gulp      npm
  
And what about a global?


->  project2 git:(dev) $ which gulp                                                  
/Users/jmunsch/.nvm/versions/node/v4.1.1/bin/gulp

->  project2 git:(dev) $ ls -li /Users/jmunsch/.nvm/versions/node/v4.1.1/bin/gulp    
12675471 lrwxr-xr-x  1 jmunsch  staff  36 Oct  7 14:35 /Users/jmunsch/.nvm/versions/node/v4.1.1/bin/gulp -> ../lib/node_modules/gulp/bin/gulp.js

->  project2 git:(dev) $ ls /Users/jmunsch/.nvm/versions/node/v4.1.1/lib/node_modules
grunt-cli gulp      npm

  

Alright so nvm keeps the node and npm versions together, which also means that it will keep the package versions together, which also means that if you switch between versions it won't break npm installs across node/npm/package versions.

BUT WAIT THERES MORE, the install procedure is the same across both linux and mac when using nvm. That's right folks it works in bash, it works in zsh, it works in ksh, it works in sh, and it works in dash.

Okay lets try to fix this, and by fix i mean break.

So here I go making things more difficult than they need to be.

sudo chown root:admin /usr/local/lib/node_modules

Oops, now root owns all the npms.



->  project2 git:(dev) $ npm install -g gulp             
npm ERR! Darwin 14.5.0
npm ERR! argv "node" "/usr/local/bin/npm" "install" "-g" "gulp"
npm ERR! node v0.12.7
npm ERR! npm  v2.12.1
npm ERR! path /usr/local/lib/node_modules/gulp
npm ERR! code EACCES
npm ERR! errno -13

npm ERR! Error: EACCES, rmdir '/usr/local/lib/node_modules/gulp'
npm ERR!     at Error (native)
npm ERR!  { [Error: EACCES, rmdir '/usr/local/lib/node_modules/gulp']
npm ERR!   errno: -13,
npm ERR!   code: 'EACCES',
npm ERR!   path: '/usr/local/lib/node_modules/gulp' }
npm ERR! 
npm ERR! Please try running this command again as root/Administrator.
npm ERR! error rolling back Error: EACCES, rmdir '/usr/local/lib/node_modules/gulp'
npm ERR! error rolling back     at Error (native)
npm ERR! error rolling back  { [Error: EACCES, rmdir '/usr/local/lib/node_modules/gulp']
npm ERR! error rolling back   errno: -13,
npm ERR! error rolling back   code: 'EACCES',
npm ERR! error rolling back   path: '/usr/local/lib/node_modules/gulp' }

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/jmunsch/Desktop/Development/project2/npm-debug.log

NOOOOOOOOOOOOOOO.



->  project2 git:(dev) $ gulp
zsh: command not found: gulp

->  project2 git:(dev) $ which gulp
gulp not found

WAIT STAND BACK I GOT THIS


->  project2 git:(dev) $ sudo npm install -g gulp
/usr/local/bin/gulp -> /usr/local/lib/node_modules/gulp/bin/gulp.js
gulp@3.9.0 /usr/local/lib/node_modules/gulp
.
.
.

->  project2 git:(dev) $ which gulp
/usr/local/bin/gulp

->  project2 git:(dev) $ stat /usr/local/bin/gulp
16777220 12748639 lrwxr-xr-x 1 root admin 0 36 "Oct  7 20:55:44 2015" "Oct  7 20:55:44 2015" "Oct  7 20:55:44 2015" "Oct  7 20:55:44 2015" 4096 8 0 /usr/local/bin/gulp

Alright great now all the sudos to get anything done, because when I npm install something to a projects node_modules they will be owned by whoever the current user is, but anytime a global needs to be installed I better have those sudos ready.



->  project2 git:(dev) $ ls -li /usr/local/bin/gulp 
12748639 lrwxr-xr-x  1 root  admin  36 Oct  7 20:55 /usr/local/bin/gulp -> ../lib/node_modules/gulp/bin/gulp.js

->  project2 git:(dev) $ ls -li /usr/local/bin/gulp 
12748639 lrwxr-xr-x  1 root  admin  36 Oct  7 20:55 /usr/local/bin/gulp -> ../lib/node_modules/gulp/bin/gulp.js

->  project2 git:(dev) $ stat node_modules/angular 
16777220 12748688 drwxr-xr-x 11 jmunsch staff 0 374 "Oct  7 20:59:37 2015" "Oct  7 20:59:37 2015" "Oct  7 20:59:37 2015" "Oct  7 20:59:37 2015" 4096 0 0 node_modules/angular

  


Taking ownership:


->  project2 git:(dev) $ sudo chown -R jmunsch:admin /usr/local/lib/node_modules
Password:

->  project2 git:(dev) $ npm install -g grunt-cli
/usr/local/bin/grunt -> /usr/local/lib/node_modules/grunt-cli/bin/grunt
grunt-cli@0.1.13 /usr/local/lib/node_modules/grunt-cli
.
.
.

  

NOOOOOOOOOOOOOOOOOO

well unless you want, but seriously just use nvm.

So if you see something like this:


  ->  project2 git:(dev) $ which node
/usr/local/bin/node

->  project2 git:(dev) $ which npm
/usr/local/bin/npm
  

Make it not appear like that. Uninstall. uninstall:


  rm -rf /usr/local/lib/node_modules
  

wait ... oops.

Drop into single user mode and weird mount the sudo driver. And try and undo the redo of the bashrc chown source trimblers.

AHHHHHH DANG IT. Alright lemme try and fix this.


->  Development $ echo 'echo haha NODE is borked better luck next time' >> node
->  Development $ rm /usr/local/bin/node 
->  Development $ ln -s $(pwd)/node /usr/local/bin/node

-> Development $  node
haha NODE is borked better luck next time
-> Development $  node -v
haha NODE is borked better luck next time
-> Development $  NODE _V
haha NODE is borked better luck next time
-> Development $  NODE NODE
haha NODE is borked better luck next time
-> Development $  node
haha NODE is borked better luck next time
-> Development $  NODE NODE NODE
haha NODE is borked better luck next time
WAIT I THERES MORE THAT I CAN TRY:

->  Development $ brew install node
Warning: node-0.12.7 already installed

->  Development $ which node
/usr/local/bin/node

->  Development $ brew reinstall node
  ==> Reinstalling node
  ==> Downloading https://homebrew.bintray.com/bottles/node-0.12.7.yosemite.bottle.tar.gz
  Already downloaded: /Library/Caches/Homebrew/node-0.12.7.yosemite.bottle.tar.gz
  ==> Pouring node-0.12.7.yosemite.bottle.tar.gz
  Error: The `brew link` step did not complete successfully
  The formula built, but is not symlinked into /usr/local
  Could not symlink bin/node
  Target /usr/local/bin/node
  already exists. You may want to remove it:
    rm '/usr/local/bin/node'

  To force the link and overwrite all conflicting files:
    brew link --overwrite node

  To list all files that would be deleted:
    brew link --overwrite --dry-run node

  Possible conflicting files are:
  /usr/local/bin/node -> /Users/jmunsch/Desktop/Development/node
  ==> Caveats
  Bash completion has been installed to:
    /usr/local/etc/bash_completion.d
  ==> Summary
  /usr/local/Cellar/node/0.12.7: 2726 files, 31M
->  Development $ yes "very sad"

Ah, now i done did it.... do i just reformat the thing? Or WAIT!?
             
-> Development $  nvm use 4
Now using node v4.1.1 (npm v2.14.4)
-> Development $  node -v
v4.1.1


Point being follow the instructions here: https://github.com/creationix/nvm


curl -o- https://raw.githubusercontent.com/creationix/nvm/MOSTCURRENTVERSIONHERE/install.sh | bash
  
(replacing the MOSTCURRENTVERSIONHERE) https://github.com/creationix/nvm

then nvm install 4, nvm install 0.12, nvm install 0.10, or nvm install iojs.

nvm use 4, nvm use 0.12, and nvm use iojs just for fun.