require() behavior changed from 0.6 to 0.8 #5038

jdduncan opened this Issue Mar 16, 2013 · 5 comments

5 participants


require() in node.js 0.8 and 0.10 seem to behave differently from 0.6, I cannot find the change documented, and I do not understand the correct way to install an executable globally when the executable depends on a module. Can anyone point me to an explanation of the behavior?

I can look at a working example, like jshint:
$ cat /usr/local/bin/jshint
#!/usr/bin/env node


But it is far from clear what "." refers to in the example. It is certainly not my current working directory.

How to repeat

  1. npm install underscore # (for example)
    "sudo npm install -g underscore" would make no difference

  2. Create file "testcase" as follows:
    #!/usr/bin/env node
    var u = require("underscore");

  3. Run locally from node (ok)
    node testcase

  4. Run locally (ok)
    chmod +x testcase

  5. Install and run from path
    sudo install testcase /usr/local/bin/
    Node 0.6 would find the underscore module, but Node 0.8 does not:

Error: Cannot find module 'underscore'
at Function.Module._resolveFilename (module.js:338:15)
at Function.Module._load (module.js:280:25)

Node.js Foundation member

I'm not the most qualified one to comment on this issue (that would be @isaacs or @TooTallNate) but -g is for installing binaries, not libraries. The module loader looks for modules in /path/to/node/../../lib/node (i.e. relative to the absolute path of the binary) but that is considered extremely deprecated by now.


@jdduncan Can you confirm the first line of npm ls -g and node -e 'console.log(process.installPrefix)', with v0.6 and v0.8?

But it is far from clear what "." refers to in the example.

"." always refers to the directory of the module itself. In the example, "." is /usr/local/bin.

@bnoordhuis -g means "global install". :)


I get this:
$ node -e 'console.log(process.installPrefix)'

And "npm ls -g" output begins with "/usr/local/lib"

Those are identical both on the machine running 0.6 and the one now running 0.10.

As for the jshint example, it turns out that /usr/local/bin/jshint is a symlink to /usr/local/lib/node_modules/jshint/bin/jshint -- so that "." refers to /usr/local/lib/node_modules/jshint/bin

So jshint is not a perfect example for my own problem -- which is that I have a script with a require('foo') statement. My script is an executable, a utility, and it ran ok from any random directory, but then after I manually installed it in /usr/local/bin it could no longer find module foo.


@tjfontaine I believe this should be closed as "this is how node module system works".


Indeed, this is working as designed

@tjfontaine tjfontaine closed this Aug 7, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment