From 0a3eff8021de38f11411369da3ea93bd9dbddd31 Mon Sep 17 00:00:00 2001 From: Nick Stenning Date: Wed, 4 Aug 2010 22:55:24 +0100 Subject: [PATCH] Standardise module load order for native and registered file extensions. 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 --- lib/module.js | 38 ++++++------------- test/fixtures/module-load-order/file1 | 1 + test/fixtures/module-load-order/file1.js | 1 + test/fixtures/module-load-order/file1.node | 1 + test/fixtures/module-load-order/file1.reg | 1 + test/fixtures/module-load-order/file1.reg2 | 1 + test/fixtures/module-load-order/file2.js | 1 + test/fixtures/module-load-order/file2.node | 1 + test/fixtures/module-load-order/file2.reg | 1 + test/fixtures/module-load-order/file2.reg2 | 1 + .../fixtures/module-load-order/file2/index.js | 1 + .../module-load-order/file2/index.node | 1 + .../module-load-order/file2/index.reg | 1 + .../module-load-order/file2/index.reg2 | 1 + test/fixtures/module-load-order/file3.node | 1 + test/fixtures/module-load-order/file3.reg | 1 + test/fixtures/module-load-order/file3.reg2 | 1 + .../fixtures/module-load-order/file3/index.js | 1 + .../module-load-order/file3/index.node | 1 + .../module-load-order/file3/index.reg | 1 + .../module-load-order/file3/index.reg2 | 1 + test/fixtures/module-load-order/file4.reg | 1 + test/fixtures/module-load-order/file4.reg2 | 1 + .../fixtures/module-load-order/file4/index.js | 1 + .../module-load-order/file4/index.node | 1 + .../module-load-order/file4/index.reg | 1 + .../module-load-order/file4/index.reg2 | 1 + test/fixtures/module-load-order/file5.reg2 | 1 + .../fixtures/module-load-order/file5/index.js | 1 + .../module-load-order/file5/index.node | 1 + .../module-load-order/file5/index.reg | 1 + .../module-load-order/file5/index.reg2 | 1 + .../fixtures/module-load-order/file6/index.js | 1 + .../module-load-order/file6/index.node | 1 + .../module-load-order/file6/index.reg | 1 + .../module-load-order/file6/index.reg2 | 1 + .../module-load-order/file7/index.node | 1 + .../module-load-order/file7/index.reg | 1 + .../module-load-order/file7/index.reg2 | 1 + .../module-load-order/file8/index.reg | 1 + .../module-load-order/file8/index.reg2 | 1 + .../module-load-order/file9/index.reg2 | 1 + test/simple/test-module-loading.js | 30 +++++++++++++++ 43 files changed, 83 insertions(+), 26 deletions(-) create mode 100644 test/fixtures/module-load-order/file1 create mode 100644 test/fixtures/module-load-order/file1.js create mode 100644 test/fixtures/module-load-order/file1.node create mode 100644 test/fixtures/module-load-order/file1.reg create mode 100644 test/fixtures/module-load-order/file1.reg2 create mode 100644 test/fixtures/module-load-order/file2.js create mode 100644 test/fixtures/module-load-order/file2.node create mode 100644 test/fixtures/module-load-order/file2.reg create mode 100644 test/fixtures/module-load-order/file2.reg2 create mode 100644 test/fixtures/module-load-order/file2/index.js create mode 100644 test/fixtures/module-load-order/file2/index.node create mode 100644 test/fixtures/module-load-order/file2/index.reg create mode 100644 test/fixtures/module-load-order/file2/index.reg2 create mode 100644 test/fixtures/module-load-order/file3.node create mode 100644 test/fixtures/module-load-order/file3.reg create mode 100644 test/fixtures/module-load-order/file3.reg2 create mode 100644 test/fixtures/module-load-order/file3/index.js create mode 100644 test/fixtures/module-load-order/file3/index.node create mode 100644 test/fixtures/module-load-order/file3/index.reg create mode 100644 test/fixtures/module-load-order/file3/index.reg2 create mode 100644 test/fixtures/module-load-order/file4.reg create mode 100644 test/fixtures/module-load-order/file4.reg2 create mode 100644 test/fixtures/module-load-order/file4/index.js create mode 100644 test/fixtures/module-load-order/file4/index.node create mode 100644 test/fixtures/module-load-order/file4/index.reg create mode 100644 test/fixtures/module-load-order/file4/index.reg2 create mode 100644 test/fixtures/module-load-order/file5.reg2 create mode 100644 test/fixtures/module-load-order/file5/index.js create mode 100644 test/fixtures/module-load-order/file5/index.node create mode 100644 test/fixtures/module-load-order/file5/index.reg create mode 100644 test/fixtures/module-load-order/file5/index.reg2 create mode 100644 test/fixtures/module-load-order/file6/index.js create mode 100644 test/fixtures/module-load-order/file6/index.node create mode 100644 test/fixtures/module-load-order/file6/index.reg create mode 100644 test/fixtures/module-load-order/file6/index.reg2 create mode 100644 test/fixtures/module-load-order/file7/index.node create mode 100644 test/fixtures/module-load-order/file7/index.reg create mode 100644 test/fixtures/module-load-order/file7/index.reg2 create mode 100644 test/fixtures/module-load-order/file8/index.reg create mode 100644 test/fixtures/module-load-order/file8/index.reg2 create mode 100644 test/fixtures/module-load-order/file9/index.reg2 diff --git a/lib/module.js b/lib/module.js index 1db1cb4507..54ed01cf38 100644 --- a/lib/module.js +++ b/lib/module.js @@ -59,8 +59,6 @@ function requireNative (id) { return loadNative(id).exports; } - - // Event var eventsFn = process.compile("(function (exports) {" + natives.events + "\n})", @@ -93,6 +91,8 @@ if (process.env["NODE_PATH"]) { modulePaths = process.env["NODE_PATH"].split(":").concat(modulePaths); } +var moduleNativeExtensions = ['js', 'node']; + /* Sync unless callback given */ function findModulePath (id, dirs, callback) { process.assert(dirs.constructor == Array); @@ -106,10 +106,6 @@ function findModulePath (id, dirs, callback) { return; } - if (/\.(js|node)$/.exec(id)) { - throw new Error("No longer accepting filename extension in module names"); - } - if (dirs.length == 0) { if (callback) { callback(); @@ -126,22 +122,17 @@ function findModulePath (id, dirs, callback) { rest = []; } - var locations = [ - path.join(dir, id + ".js"), - path.join(dir, id + ".node"), - path.join(dir, id, "index.js"), - path.join(dir, id, "index.node"), - path.join(dir, id) - ]; + var ext, locDirect = [], locIndex = []; + var extensions = moduleNativeExtensions.concat(Object.keys(extensionCache)); - var ext; - var extensions = Object.keys(extensionCache); for (var i = 0, l = extensions.length; i < l; i++) { - var ext = extensions[i]; - locations.push(path.join(dir, id + ext)); - locations.push(path.join(dir, id, 'index' + ext)); + ext = extensions[i]; + locDirect.push(path.join(dir, id + '.' + ext)); + locIndex.push(path.join(dir, id, 'index.' + ext)); } + var locations = [path.join(dir, id)].concat(locDirect).concat(locIndex); + var fs = requireNative('fs'); function searchLocations () { @@ -192,12 +183,7 @@ function resolveModulePath(request, parent) { if (request.charAt(0) == "." && (request.charAt(1) == "/" || request.charAt(1) == ".")) { // Relative request - var exts = ['js', 'node'], ext; - var extensions = Object.keys(extensionCache); - for (var i = 0, l = extensions.length; i < l; i++) { - var ext = extensions[i]; - exts.push(ext.slice(1)); - } + var exts = moduleNativeExtensions.concat(Object.keys(extensionCache)); var parentIdPath = path.dirname(parent.id + (path.basename(parent.filename).match(new RegExp('^index\\.(' + exts.join('|') + ')$')) ? "/." : "")); @@ -293,7 +279,7 @@ function registerExtension(ext, compiler) { throw new Error('require.registerExtension: Second argument not a valid compiler function.'); } - extensionCache[ext] = compiler; + extensionCache[ext.slice(1)] = compiler; } @@ -364,7 +350,7 @@ Module.prototype._compile = function (content, filename) { content = content.replace(/^\#\!.*/, ''); // Compile content if needed - var ext = path.extname(filename); + var ext = path.extname(filename).slice(1); if (extensionCache[ext]) { content = extensionCache[ext](content); } diff --git a/test/fixtures/module-load-order/file1 b/test/fixtures/module-load-order/file1 new file mode 100644 index 0000000000..7f287a858c --- /dev/null +++ b/test/fixtures/module-load-order/file1 @@ -0,0 +1 @@ +exports.file1 = 'file1'; diff --git a/test/fixtures/module-load-order/file1.js b/test/fixtures/module-load-order/file1.js new file mode 100644 index 0000000000..d4ab32cb7a --- /dev/null +++ b/test/fixtures/module-load-order/file1.js @@ -0,0 +1 @@ +exports.file1 = 'file1.js'; diff --git a/test/fixtures/module-load-order/file1.node b/test/fixtures/module-load-order/file1.node new file mode 100644 index 0000000000..af84f6510f --- /dev/null +++ b/test/fixtures/module-load-order/file1.node @@ -0,0 +1 @@ +exports.file1 = 'file1.node'; diff --git a/test/fixtures/module-load-order/file1.reg b/test/fixtures/module-load-order/file1.reg new file mode 100644 index 0000000000..857b61b6c2 --- /dev/null +++ b/test/fixtures/module-load-order/file1.reg @@ -0,0 +1 @@ +exports.file1 = 'file1.reg'; diff --git a/test/fixtures/module-load-order/file1.reg2 b/test/fixtures/module-load-order/file1.reg2 new file mode 100644 index 0000000000..c38de9cc6b --- /dev/null +++ b/test/fixtures/module-load-order/file1.reg2 @@ -0,0 +1 @@ +exports.file1 = 'file1.reg2'; diff --git a/test/fixtures/module-load-order/file2.js b/test/fixtures/module-load-order/file2.js new file mode 100644 index 0000000000..0b1af928ca --- /dev/null +++ b/test/fixtures/module-load-order/file2.js @@ -0,0 +1 @@ +exports.file2 = 'file2.js'; diff --git a/test/fixtures/module-load-order/file2.node b/test/fixtures/module-load-order/file2.node new file mode 100644 index 0000000000..2c7c4b6c9f --- /dev/null +++ b/test/fixtures/module-load-order/file2.node @@ -0,0 +1 @@ +exports.file2 = 'file2.node'; diff --git a/test/fixtures/module-load-order/file2.reg b/test/fixtures/module-load-order/file2.reg new file mode 100644 index 0000000000..ee5edebf51 --- /dev/null +++ b/test/fixtures/module-load-order/file2.reg @@ -0,0 +1 @@ +exports.file2 = 'file2.reg'; diff --git a/test/fixtures/module-load-order/file2.reg2 b/test/fixtures/module-load-order/file2.reg2 new file mode 100644 index 0000000000..95c2a59268 --- /dev/null +++ b/test/fixtures/module-load-order/file2.reg2 @@ -0,0 +1 @@ +exports.file2 = 'file2.reg2'; diff --git a/test/fixtures/module-load-order/file2/index.js b/test/fixtures/module-load-order/file2/index.js new file mode 100644 index 0000000000..20c642bf2e --- /dev/null +++ b/test/fixtures/module-load-order/file2/index.js @@ -0,0 +1 @@ +exports.file2 = 'file2/index.js'; diff --git a/test/fixtures/module-load-order/file2/index.node b/test/fixtures/module-load-order/file2/index.node new file mode 100644 index 0000000000..a987dc4938 --- /dev/null +++ b/test/fixtures/module-load-order/file2/index.node @@ -0,0 +1 @@ +exports.file2 = 'file2/index.node'; diff --git a/test/fixtures/module-load-order/file2/index.reg b/test/fixtures/module-load-order/file2/index.reg new file mode 100644 index 0000000000..61d7b9164b --- /dev/null +++ b/test/fixtures/module-load-order/file2/index.reg @@ -0,0 +1 @@ +exports.file2 = 'file2/index.reg'; diff --git a/test/fixtures/module-load-order/file2/index.reg2 b/test/fixtures/module-load-order/file2/index.reg2 new file mode 100644 index 0000000000..ecc8240f3d --- /dev/null +++ b/test/fixtures/module-load-order/file2/index.reg2 @@ -0,0 +1 @@ +exports.file2 = 'file2/index.reg2'; diff --git a/test/fixtures/module-load-order/file3.node b/test/fixtures/module-load-order/file3.node new file mode 100644 index 0000000000..f9d478429e --- /dev/null +++ b/test/fixtures/module-load-order/file3.node @@ -0,0 +1 @@ +exports.file3 = 'file3.node'; diff --git a/test/fixtures/module-load-order/file3.reg b/test/fixtures/module-load-order/file3.reg new file mode 100644 index 0000000000..41e5b9f0ba --- /dev/null +++ b/test/fixtures/module-load-order/file3.reg @@ -0,0 +1 @@ +exports.file3 = 'file3.reg'; diff --git a/test/fixtures/module-load-order/file3.reg2 b/test/fixtures/module-load-order/file3.reg2 new file mode 100644 index 0000000000..902a0a0423 --- /dev/null +++ b/test/fixtures/module-load-order/file3.reg2 @@ -0,0 +1 @@ +exports.file3 = 'file3.reg2'; diff --git a/test/fixtures/module-load-order/file3/index.js b/test/fixtures/module-load-order/file3/index.js new file mode 100644 index 0000000000..5ec373cad7 --- /dev/null +++ b/test/fixtures/module-load-order/file3/index.js @@ -0,0 +1 @@ +exports.file3 = 'file3/index.js'; diff --git a/test/fixtures/module-load-order/file3/index.node b/test/fixtures/module-load-order/file3/index.node new file mode 100644 index 0000000000..451e075d7a --- /dev/null +++ b/test/fixtures/module-load-order/file3/index.node @@ -0,0 +1 @@ +exports.file3 = 'file3/index.node'; diff --git a/test/fixtures/module-load-order/file3/index.reg b/test/fixtures/module-load-order/file3/index.reg new file mode 100644 index 0000000000..b93aa809d1 --- /dev/null +++ b/test/fixtures/module-load-order/file3/index.reg @@ -0,0 +1 @@ +exports.file3 = 'file3/index.reg'; diff --git a/test/fixtures/module-load-order/file3/index.reg2 b/test/fixtures/module-load-order/file3/index.reg2 new file mode 100644 index 0000000000..4e1d9cce1f --- /dev/null +++ b/test/fixtures/module-load-order/file3/index.reg2 @@ -0,0 +1 @@ +exports.file3 = 'file3/index.reg2'; diff --git a/test/fixtures/module-load-order/file4.reg b/test/fixtures/module-load-order/file4.reg new file mode 100644 index 0000000000..1026207d49 --- /dev/null +++ b/test/fixtures/module-load-order/file4.reg @@ -0,0 +1 @@ +exports.file4 = 'file4.reg'; diff --git a/test/fixtures/module-load-order/file4.reg2 b/test/fixtures/module-load-order/file4.reg2 new file mode 100644 index 0000000000..62e134189d --- /dev/null +++ b/test/fixtures/module-load-order/file4.reg2 @@ -0,0 +1 @@ +exports.file4 = 'file4.reg2'; diff --git a/test/fixtures/module-load-order/file4/index.js b/test/fixtures/module-load-order/file4/index.js new file mode 100644 index 0000000000..f28889d98a --- /dev/null +++ b/test/fixtures/module-load-order/file4/index.js @@ -0,0 +1 @@ +exports.file4 = 'file4/index.js'; diff --git a/test/fixtures/module-load-order/file4/index.node b/test/fixtures/module-load-order/file4/index.node new file mode 100644 index 0000000000..a4f7a0ba3c --- /dev/null +++ b/test/fixtures/module-load-order/file4/index.node @@ -0,0 +1 @@ +exports.file4 = 'file4/index.node'; diff --git a/test/fixtures/module-load-order/file4/index.reg b/test/fixtures/module-load-order/file4/index.reg new file mode 100644 index 0000000000..e7c5fae069 --- /dev/null +++ b/test/fixtures/module-load-order/file4/index.reg @@ -0,0 +1 @@ +exports.file4 = 'file4/index.reg'; diff --git a/test/fixtures/module-load-order/file4/index.reg2 b/test/fixtures/module-load-order/file4/index.reg2 new file mode 100644 index 0000000000..c52c1087c7 --- /dev/null +++ b/test/fixtures/module-load-order/file4/index.reg2 @@ -0,0 +1 @@ +exports.file4 = 'file4/index.reg2'; diff --git a/test/fixtures/module-load-order/file5.reg2 b/test/fixtures/module-load-order/file5.reg2 new file mode 100644 index 0000000000..651141c147 --- /dev/null +++ b/test/fixtures/module-load-order/file5.reg2 @@ -0,0 +1 @@ +exports.file5 = 'file5.reg2'; diff --git a/test/fixtures/module-load-order/file5/index.js b/test/fixtures/module-load-order/file5/index.js new file mode 100644 index 0000000000..737945ffb5 --- /dev/null +++ b/test/fixtures/module-load-order/file5/index.js @@ -0,0 +1 @@ +exports.file5 = 'file5/index.js'; diff --git a/test/fixtures/module-load-order/file5/index.node b/test/fixtures/module-load-order/file5/index.node new file mode 100644 index 0000000000..07c559d413 --- /dev/null +++ b/test/fixtures/module-load-order/file5/index.node @@ -0,0 +1 @@ +exports.file5 = 'file5/index.node'; diff --git a/test/fixtures/module-load-order/file5/index.reg b/test/fixtures/module-load-order/file5/index.reg new file mode 100644 index 0000000000..75c2ab42ff --- /dev/null +++ b/test/fixtures/module-load-order/file5/index.reg @@ -0,0 +1 @@ +exports.file5 = 'file5/index.reg'; diff --git a/test/fixtures/module-load-order/file5/index.reg2 b/test/fixtures/module-load-order/file5/index.reg2 new file mode 100644 index 0000000000..82004742be --- /dev/null +++ b/test/fixtures/module-load-order/file5/index.reg2 @@ -0,0 +1 @@ +exports.file5 = 'file5/index.reg2'; diff --git a/test/fixtures/module-load-order/file6/index.js b/test/fixtures/module-load-order/file6/index.js new file mode 100644 index 0000000000..4228429e92 --- /dev/null +++ b/test/fixtures/module-load-order/file6/index.js @@ -0,0 +1 @@ +exports.file6 = 'file6/index.js'; diff --git a/test/fixtures/module-load-order/file6/index.node b/test/fixtures/module-load-order/file6/index.node new file mode 100644 index 0000000000..c77e34b31f --- /dev/null +++ b/test/fixtures/module-load-order/file6/index.node @@ -0,0 +1 @@ +exports.file6 = 'file6/index.node'; diff --git a/test/fixtures/module-load-order/file6/index.reg b/test/fixtures/module-load-order/file6/index.reg new file mode 100644 index 0000000000..5eeff75543 --- /dev/null +++ b/test/fixtures/module-load-order/file6/index.reg @@ -0,0 +1 @@ +exports.file6 = 'file6/index.reg'; diff --git a/test/fixtures/module-load-order/file6/index.reg2 b/test/fixtures/module-load-order/file6/index.reg2 new file mode 100644 index 0000000000..391a008c31 --- /dev/null +++ b/test/fixtures/module-load-order/file6/index.reg2 @@ -0,0 +1 @@ +exports.file6 = 'file6/index.reg2'; diff --git a/test/fixtures/module-load-order/file7/index.node b/test/fixtures/module-load-order/file7/index.node new file mode 100644 index 0000000000..350ffbff89 --- /dev/null +++ b/test/fixtures/module-load-order/file7/index.node @@ -0,0 +1 @@ +exports.file7 = 'file7/index.node'; diff --git a/test/fixtures/module-load-order/file7/index.reg b/test/fixtures/module-load-order/file7/index.reg new file mode 100644 index 0000000000..bff6ec3df5 --- /dev/null +++ b/test/fixtures/module-load-order/file7/index.reg @@ -0,0 +1 @@ +exports.file7 = 'file7/index.reg'; diff --git a/test/fixtures/module-load-order/file7/index.reg2 b/test/fixtures/module-load-order/file7/index.reg2 new file mode 100644 index 0000000000..a4e1093613 --- /dev/null +++ b/test/fixtures/module-load-order/file7/index.reg2 @@ -0,0 +1 @@ +exports.file7 = 'file7/index.reg2'; diff --git a/test/fixtures/module-load-order/file8/index.reg b/test/fixtures/module-load-order/file8/index.reg new file mode 100644 index 0000000000..278d047345 --- /dev/null +++ b/test/fixtures/module-load-order/file8/index.reg @@ -0,0 +1 @@ +exports.file8 = 'file8/index.reg'; diff --git a/test/fixtures/module-load-order/file8/index.reg2 b/test/fixtures/module-load-order/file8/index.reg2 new file mode 100644 index 0000000000..5522829fd2 --- /dev/null +++ b/test/fixtures/module-load-order/file8/index.reg2 @@ -0,0 +1 @@ +exports.file8 = 'file8/index.reg2'; diff --git a/test/fixtures/module-load-order/file9/index.reg2 b/test/fixtures/module-load-order/file9/index.reg2 new file mode 100644 index 0000000000..c747b1e571 --- /dev/null +++ b/test/fixtures/module-load-order/file9/index.reg2 @@ -0,0 +1 @@ +exports.file9 = 'file9/index.reg2'; diff --git a/test/simple/test-module-loading.js b/test/simple/test-module-loading.js index 7405c0887f..7a62d76cde 100644 --- a/test/simple/test-module-loading.js +++ b/test/simple/test-module-loading.js @@ -123,6 +123,36 @@ require.async("../fixtures/empty", function (err, a) { } }); +// Check load order is as expected +common.debug('load order'); + +var loadOrder = '../fixtures/module-load-order/', + msg = "Load order incorrect."; + +require.registerExtension('.reg', function(content) { return content; }); +require.registerExtension('.reg2', function(content) { return content; }); + +assert.equal(require(loadOrder + 'file1').file1, 'file1', msg); +assert.equal(require(loadOrder + 'file2').file2, 'file2.js', msg); +try { + require(loadOrder + 'file3'); +} catch (e) { + // Not a real .node module, but we know we require'd the right thing. + assert.ok(e.message.match(/^dlopen/)); + assert.ok(e.message.match(/file3\.node/)); +} +assert.equal(require(loadOrder + 'file4').file4, 'file4.reg', msg); +assert.equal(require(loadOrder + 'file5').file5, 'file5.reg2', msg); +assert.equal(require(loadOrder + 'file6').file6, 'file6/index.js', msg); +try { + require(loadOrder + 'file7'); +} catch (e) { + assert.ok(e.message.match(/^dlopen/)); + assert.ok(e.message.match(/file7\/index\.node/)); +} +assert.equal(require(loadOrder + 'file8').file8, 'file8/index.reg', msg); +assert.equal(require(loadOrder + 'file9').file9, 'file9/index.reg2', msg); + process.addListener("exit", function () { assert.equal(true, a.A instanceof Function); assert.equal("A done", a.A());