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.
Currently the module tests don't cover the cases for when a user
requires a file with a request that includes the extension, and for a
request to a file with no extensions.
ex.
require("./a.js") // not tested
require("./foo") // (not tested with trying to load a file named ./foo)
This patch removes require.async from nodejs.
1. It complicated the code unnecessarily.
2. Everyone uses sync require anyway.
3. It's got a lot of weird edge cases when mixed with sync require.
4. It is many months behind the commonjs spec anyhow.
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.
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.