How to npm install global not as root?

I'm on a unix box where I don't have root access.

I changed my .npmrc file (in my user's root directory) to:

prefix=~/global_npm

Now when I do "npm install -g packagename" it installs inside my global_npm directory. Which is good. And then I gave myself path access to it by updating my .bashrc file with:

export PATH=$PATH:~/global_npm/bin

Do I need to do anything else? I think I need to set NODE_PATH but I'm not sure?

57589 次浏览

That's pretty much all you need to do if you are installing binary utilities (which I gather you are as you updated your PATH).

NODE_PATH will only need to be set you have installed a module that you want to require() from unrelated node scripts, but you shouldn't really do this anyway. Modules that are required as dependencies for other modules/scripts should be installed locally (i.e. specified in a package.json) as that way you keep strict control over versions.

Edit: The accepted answer here explains it much better than I was able to: How do I install a module globally using npm?

  1. Either start a new terminal session or just type "source ~/.bashrc"
  2. Now you can run any executables like grunt/bower/yo/whatever (depending on what npm packages you have installed globally).

P.S. BTW changing the global npm directory can be done with a command: npm config set prefix ~/global_npm

Try to switch user:

su - username

If you don't have another user try:

useradd username

Then,

su - username

Sindre Sorhus has a great guide at github.com/sindresorhus/guides which I've reposted here.


Install npm packages globally without sudo on OS X and Linux

npm installs packages locally within your projects by default. You can also install packages globally (e.g. npm install -g <package>) (useful for command-line apps). However the downside of this is that you need to be root (or use sudo) to be able to install globally.

Here is a way to install packages globally for a given user.

1. Create a directory for your global packages

mkdir "${HOME}/.npm-packages"

2. Reference this directory for future usage in your .bashrc/.zshrc:

NPM_PACKAGES="${HOME}/.npm-packages"

3. Indicate to npm where to store your globally installed package. In your $HOME/.npmrc file add:

prefix=${HOME}/.npm-packages

4. Ensure node will find them. Add the following to your .bashrc/.zshrc:

NODE_PATH="$NPM_PACKAGES/lib/node_modules:$NODE_PATH"

5. Ensure you'll find installed binaries and man pages. Add the following to your .bashrc/.zshrc:

PATH="$NPM_PACKAGES/bin:$PATH"
# Unset manpath so we can inherit from /etc/manpath via the `manpath`
# command
unset MANPATH # delete if you already modified MANPATH elsewhere in your config
MANPATH="$NPM_PACKAGES/share/man:$(manpath)"

Check out npm-g_nosudo for doing the above steps automagically


NOTE: If you are running OS X, the .bashrc file may not yet exist, and the terminal will be obtaining its environment parameters from another file, such as .profile or .bash_profile. These files also reside in the user's home folder. In this case, simply adding the following line to them will instruct Terminal to also load the .bashrc file:

source ~/.bashrc

Unless you require a package installation due to dependencies, which are rare, I would recommend you use NVM (https://github.com/creationix/nvm) to install Node.

If you do this without sudo, you will also not need to use sudo when globally installing modules.

The answer by Rowno works for me, but only after making a slight edit to step 4:

NODE_PATH="$NPM_PACKAGES/lib/node_modules:$NODE_PATH"

and changed it to:

NODE_PATH="$NPM_PACKAGES/node_modules:$NODE_PATH"

My edit to Rowno's answer has been rejected and I can't make a comment yet so I'll just post my version of the lines added in .bashrc here.

The edit I made in it was adding export to the assignments of NODE_PATH and MAN_PATH, and then simplifying the MANPATH assignment. I also made : optional for NODE_PATH just in case it doesn't have a prior value. The other modifications here are just personal preference but I haven't included them in the original edit.

npm_global=~/.npm-global
export NODE_PATH="$npm_global/lib/node_modules${NODE_PATH:+:}$NODE_PATH"
PATH="$npm_global/bin:$PATH"
export MANPATH="$npm_global/share/man:$(unset MANPATH; manpath)"

Having export makes sure variables are shared across child processes that may need them (e.g. node and man), just in case they haven't been declared yet, or assigned with export attribute previously. Specifying export to PATH OTOH is very much optional.

I actually find it unusual to reset MANPATH before prepending a value to it because some scripts may also add custom values to it earlier. I recommend that the user makes sure .bashrc or any other user-based initialization scripts doesn't add other lines like this at least. For global configurations, I think the path should be added formally through /etc/manpath.config, or something similar, so it's a different worry most likely.

Many setups already expect binaries to be found in ~/.local/bin/. So this answer follows that convention. Other files will get installed to ~/.local/lib/node_modules/.

1. Configure npm

Run:

npm config set prefix '~/.local/'

This modifies ~/.npmrc to include this line:

prefix=~/.local/

2. Make sure ~/.local/bin exists and is in your PATH

Run echo "$PATH" to have a look at your path. If it does not include ~/.local/bin/ already, you will need to configure your system to include it.

mkdir -p ~/.local/bin
echo 'export PATH=~/.local/bin/:$PATH' >> ~/.bashrc

Replace .bashrc with the configuration file of the shell that you are using.

3. Install packages globally

npm install -g packagename