20

I can't figure out how to add paths to my Node.js installation (v.0.4.7 on Mac OS X). I've installed npm, and it installs globally to /usr/local/lib/node_modules. However, when I installed npm, it didn't notify Node about where it chose to put global modules (should it have?). Now when I use Node in command-line mode, I can't simply require() my globally-installed modules. So, I'm wondering if there is some kind of Node configuration file or environment variable where I can add my global npm module installation path?

I know that I can just add it to the require.paths array when I'm in Node's command line, but I want to add this global module folder once and for all, so that Node will always search that directory for modules when I require() them from the command line. Thanks in advance for any help and pointers about making npm and Node co-exist!

2
  • what version of npm are you using? how do you require on the command line? are you using require("./module"); or require("module");? Commented May 5, 2011 at 7:36
  • i'm using npm 1.0.5. I was using require('module') in the Node command line. I installed these modules with the -g option and they went to the global module directory, but Node doesn't know about this dir for some reason... Commented May 5, 2011 at 17:02

4 Answers 4

19

OK, I got it. Combining info from http://nodejs.org/docs/v0.4.7/api/modules.html#file_Modules and https://github.com/isaacs/npm/blob/master/doc/faq.md#readme it is clear that Node checks the NODE_PATH environment variable when checking for modules. To set this I did the following:

echo 'export NODE_PATH="'$(npm root -g)'"' >> ~/.bashrc

This sets NODE_PATH to npm's global install folder.

Sign up to request clarification or add additional context in comments.

3 Comments

The drawback is that this gives you the old "everything is global" behaviour that is discuraged as npm 1.0 (global modules are added to the path also when node is not started in the repl). Another way is to have a folder dedicated to node repl sessions, with all the needed modules locally installed. Then when I want to use the repl I could simply cd to that folder.
How does it give 'everything is global' behavior?
Since you added the global module path to your .bashrc, all node invocations will use it. I'd rather limit the global behaviour to the interactive (repl) sessions.
4

Damn, I misunderstood. Sorry about that.

Back in topic, you can put these two lines in set-repl-paths.js

require.paths.unshift('/usr/lib/node_modules');
require("repl").start();

Then executing node set-repl-paths.js you will have a repl with the paths already setted. You can write a simple bash script or set a shell alias so you can just type node-repl or something similar.

With npm 1.x you should use local installation, and leave global installation for modules that provide command line utilities.

If you really want global install for module foo, then in your module folder issue a npm link foo. Now you can require("foo") in your module.

Best practice is to use local installation.

See npm 1.0: Global vs Local installation on the nodejs blog.

2 Comments

I have been through the npm documentation, and am aware of global vs local installs. This doesn't tell me anything about setting node.js paths.
+1. Thanks, rjack, this is a nice workaround. But you don't know where Node stores the paths that it uses to search for modules?
2

To install a package globally (typically used by the command line)

npm install --global PACKAGE_NAME

In my case I wanted to install jslint as a command line tool. So I ran

npm install --global jslint

This installs the package to

/usr/local/lib/node_modules/

So why all of this? You shouldn't be installing packages globally if they're being used specifically in a project.

For more information checkout the help pages.

npm help install

npm help global

I also found it in the npm FAQ

Comments

1

In reply to this: https://stackoverflow.com/a/5923898/7381355

You can add this to your .bashrc to only set NODE_PATH when running the repl since requiring global modules is an anti-pattern.

node() {
  if (( $# == 0 )); then
    NODE_PATH=$(npm root -g) command node
  else
    command node "$@"
  fi
}

It sets NODE_PATH when no arguments are passed to node. So it wouldn't work with something like node -i. You would have to add more argument checking to cover all cases a repl is run.

This would make the repl always set NODE_PATH. If you want to be able to choose whether to run the repl or a script with global modules or not, you can add this to your .bashrc instead.

node_global() {
  NODE_PATH=$(npm root -g) node "$@"
}

Then just run node_global. I went with the second option.

3 Comments

So which question are you replying to, this one, or the one you linked to?
The question I linked to is the same question as this one. I don't have enough rep to comment on that answer. I was referring to the problem Giacomo mentioned about being able to require global modules when not in a repl. stackoverflow.com/questions/5892997/… My answer is similar to Giacomo's answer stackoverflow.com/a/5908994/7381355 but it doesn't require an extra file. It's kinda like a merge of the two answers.
So what you should then do is provide the part of your answer that is relevant to this specific question here, and then provide the part of your answer that is relevant to the other question there. Even though an answer has already been accepted over there, that doesn't mean you can't add another one. (Besides, the asker of the other question has not been notified about this new answer, so it does them little help anyway when it's over here.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.