So instead of:
node.js:201
throw e; // process.nextTick error, or 'error' event on first tick
^
You will now see:
path/to/foo.js:1
throw new Error('bar');
^
This is a sub-set of isaacs patch here:
https://github.com/joyent/node/issues/3235
The difference is that this patch purely adresses the exception output,
but does not try to make any behavior changes / improvements.
The current behaviour will silently ignore any parsing errors
that may occur when loading a package.json file. This makes
debugging errors in the package.json file very difficult.
This changes the behaviour that that errors opening and reading
the file package.json file continue to be ignored, but errors
in parsing will throw an exception.
If hasOwnProperty is overridden, then calling `obj.hasOwnProperty(prop)`
can fail. Any time a dictionary of user-generated items is built, we
cannot rely on hasOwnProperty being safe, so must call it from the
Object.prototype explicitly.
Module.globalPaths is still set to a read-only copy of the global
include paths pulled off of the NODE_PATH environment variable.
It's important to be able to inspect this, but modifying it no longer
has any effect.
This adds support for a cache object to be passed to the
fs.realpath and fs.realpathSync functions. The Module loader keeps an
object around which caches the resulting realpaths that it looks up in
the process of loading modules.
This means that (at least as a result of loading modules) the same files
and folders are never lstat()ed more than once. To reset the cache, set
require("module")._realpathCache to an empty object. To disable the
caching behavior, set it to null.
This adds basic support for situations where there is a package.json
with a "main" field. That "main" module is used as the code that is
loaded when the package folder is required.
This patch standardises the load order for modules. Highest priority is trying to load exactly the file the user specified, followed by native extensions, followed by registered extra extensions, etc.
In full, if we require('foo') having registered '.coffee' as an alternative extension, we try and load the following files in order:
foo
foo.js
foo.node
foo.coffee
foo/index.js
foo/index.node
foo/index.coffee
This patch replaces the path.exists check for module loading with a call to
fs.statSync (or fs.stat for require.async) which ensures that it's not trying
to load a directory.
Before there was this comment:
Can't strip trailing slashes since module.js incorrectly
thinks dirname('/a/b/') should yield '/a/b' instead of '/a'.
But now, such thinking is corrected.
This is ever so slightly less efficient than caching based on ID, since the
filename has to be looked up before we can check the cache. However, it's
the most minimal approach possible to get this change in place. Since
require() is a blocking startup-time operation anyway, a bit of slowness is
not a huge problem.
A test involving require.paths modification and absolute loading. Here's the
gist of it.
Files: /p1/foo.js /p2/foo.js
1. Add "/p1" to require.paths.
2. foo1 = require("foo")
3. assert foo1 === require("/p1/foo") (fail)
4. Remove /p1 from require.paths.
5. Add /p2 to require.paths.
6. foo2 = require("foo")
7. assert foo1 !== foo2 (fail)
8. assert foo2 === require("/p2/foo") (fail)
It's an edge case, but it affects how dependencies are mapped by npm.
If your module requires foo-1.2.3, and my module requires foo-2.3.4,
then you should expect to have require("foo") give you foo-1.2.3, and
I should expect require("foo") to give me foo-2.3.4. However, with
module ID based caching, if your code loads *first*, then your "foo"
is THE "foo", so I'll get your version instead of mine.
It hasn't yet been a problem, but only because there are so few
modules, and everyone pretty much uses the latest version all the
time. But as things start to get to the 1.x and 2.x versions, it'll
be an issue, I'm sure. Dependency hell isn't fun, so this is a way to
avoid it before it strikes.