Skip to content

Instantly share code, notes, and snippets.

@piscisaureus
Created April 23, 2012 22:39
Show Gist options
  • Save piscisaureus/2474317 to your computer and use it in GitHub Desktop.
Save piscisaureus/2474317 to your computer and use it in GitHub Desktop.
From 0550f21f060615a72878eb3fe888191bb48d74d1 Mon Sep 17 00:00:00 2001
From: Bert Belder <[email protected]>
Date: Tue, 24 Apr 2012 00:38:24 +0200
Subject: [PATCH 1/1] Put require.paths back
---
doc/node.1 | 3 +-
lib/module.js | 26 +++++---------------
lib/repl.js | 5 +--
test/fixtures/require-path/p1/bar.js | 29 ++++++++++++++++++++++++
test/fixtures/require-path/p1/foo.js | 23 +++++++++++++++++++
test/fixtures/require-path/p2/bar.js | 23 +++++++++++++++++++
test/fixtures/require-path/p2/foo.js | 23 +++++++++++++++++++
test/simple/test-module-loading.js | 9 ++++---
test/simple/test-require-cache-without-stat.js | 12 ++++-----
9 files changed, 119 insertions(+), 34 deletions(-)
create mode 100644 test/fixtures/require-path/p1/bar.js
create mode 100644 test/fixtures/require-path/p1/foo.js
create mode 100644 test/fixtures/require-path/p2/bar.js
create mode 100644 test/fixtures/require-path/p2/foo.js
diff --git a/doc/node.1 b/doc/node.1
index f17ccda..1a47adb 100644
--- a/doc/node.1
+++ b/doc/node.1
@@ -44,7 +44,8 @@ and servers.
.SH ENVIRONMENT VARIABLES
.IP NODE_PATH
-\':\'\-separated list of directories prefixed to the module search path.
+\':\'\-separated list of directories prefixed to the module search path,
+require.paths.
.IP NODE_MODULE_CONTEXTS
If set to 1 then modules will load in their own global contexts.
diff --git a/lib/module.js b/lib/module.js
index bf90c96..ee2ec70 100644
--- a/lib/module.js
+++ b/lib/module.js
@@ -52,8 +52,7 @@ Module._contextLoad = (+process.env['NODE_MODULE_CONTEXTS'] > 0);
Module._cache = {};
Module._pathCache = {};
Module._extensions = {};
-var modulePaths = [];
-Module.globalPaths = [];
+Module._paths = [];
Module.wrapper = NativeModule.wrapper;
Module.wrap = NativeModule.wrap;
@@ -234,7 +233,7 @@ Module._resolveLookupPaths = function(request, parent) {
var start = request.substring(0, 2);
if (start !== './' && start !== '..') {
- var paths = modulePaths;
+ var paths = Module._paths;
if (parent) {
if (!parent.paths) parent.paths = [];
paths = parent.paths.concat(paths);
@@ -246,7 +245,7 @@ Module._resolveLookupPaths = function(request, parent) {
if (!parent || !parent.id || !parent.filename) {
// make require('./path/to/foo') work - normally the path is taken
// from realpath(__filename) but with eval there is no filename
- var mainPaths = ['.'].concat(modulePaths);
+ var mainPaths = ['.'].concat(Module._paths);
mainPaths = Module._nodeModulePaths('.').concat(mainPaths);
return [request, mainPaths];
}
@@ -372,23 +371,15 @@ Module.prototype._compile = function(content, filename) {
require.resolve = function(request) {
return Module._resolveFilename(request, self);
- };
-
- Object.defineProperty(require, 'paths', { get: function() {
- throw new Error('require.paths is removed. Use ' +
- 'node_modules folders, or the NODE_PATH ' +
- 'environment variable instead.');
- }});
-
+ }
+ require.paths = Module._paths;
require.main = process.mainModule;
-
// Enable support to add extra extension types
require.extensions = Module._extensions;
require.registerExtension = function() {
throw new Error('require.registerExtension() removed. Use ' +
'require.extensions instead.');
- };
-
+ }
require.cache = Module._cache;
var dirname = path.dirname(filename);
@@ -492,10 +483,7 @@ Module._initPaths = function() {
paths = process.env['NODE_PATH'].split(splitter).concat(paths);
}
- modulePaths = paths;
-
- // clone as a read-only copy, for introspection.
- Module.globalPaths = modulePaths.slice(0);
+ Module._paths = paths;
};
// bootstrap repl
diff --git a/lib/repl.js b/lib/repl.js
index 20fa7ae..9499301 100644
--- a/lib/repl.js
+++ b/lib/repl.js
@@ -381,9 +381,8 @@ REPLServer.prototype.complete = function(line, callback) {
var filter = match[1];
var dir, files, f, name, base, ext, abs, subfiles, s;
group = [];
- var paths = module.paths.concat(require('module').globalPaths);
- for (i = 0; i < paths.length; i++) {
- dir = path.resolve(paths[i], subdir);
+ for (i = 0; i < require.paths.length; i++) {
+ dir = path.resolve(require.paths[i], subdir);
try {
files = fs.readdirSync(dir);
} catch (e) {
diff --git a/test/fixtures/require-path/p1/bar.js b/test/fixtures/require-path/p1/bar.js
new file mode 100644
index 0000000..c664387
--- /dev/null
+++ b/test/fixtures/require-path/p1/bar.js
@@ -0,0 +1,29 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var path = require('path');
+
+require.paths.unshift(path.join(__dirname, '../p2'));
+
+exports.foo = require('foo');
+
+exports.expect = require(path.join(__dirname, '../p2/bar'));
+exports.actual = exports.foo.bar;
diff --git a/test/fixtures/require-path/p1/foo.js b/test/fixtures/require-path/p1/foo.js
new file mode 100644
index 0000000..b0a5a2a
--- /dev/null
+++ b/test/fixtures/require-path/p1/foo.js
@@ -0,0 +1,23 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+require.paths.unshift(__dirname);
+exports.bar = require('bar');
diff --git a/test/fixtures/require-path/p2/bar.js b/test/fixtures/require-path/p2/bar.js
new file mode 100644
index 0000000..9547039
--- /dev/null
+++ b/test/fixtures/require-path/p2/bar.js
@@ -0,0 +1,23 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+exports.INBAR = __filename;
diff --git a/test/fixtures/require-path/p2/foo.js b/test/fixtures/require-path/p2/foo.js
new file mode 100644
index 0000000..afd4401
--- /dev/null
+++ b/test/fixtures/require-path/p2/foo.js
@@ -0,0 +1,23 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+require.paths.unshift(__dirname);
+exports.bar = require('bar'); // surprise! this is not /p2/bar, this is /p1/bar
diff --git a/test/simple/test-module-loading.js b/test/simple/test-module-loading.js
index fd6735f..cb72132 100644
--- a/test/simple/test-module-loading.js
+++ b/test/simple/test-module-loading.js
@@ -146,14 +146,15 @@ require.extensions['.test'] = function(module, filename) {
};
assert.equal(require('../fixtures/registerExt2').custom, 'passed');
+common.debug('load modules by absolute id, then change require.paths, ' +
+ 'and load another module with the same absolute id.');
+// this will throw if it fails.
+var foo = require('../fixtures/require-path/p1/foo');
+assert.ok(foo.bar.expect === foo.bar.actual);
assert.equal(require('../fixtures/foo').foo, 'ok',
'require module with no extension');
-assert.throws(function() {
- require.paths;
-}, /removed/, 'Accessing require.paths should throw.');
-
// Should not attempt to load a directory
try {
require('../fixtures/empty');
diff --git a/test/simple/test-require-cache-without-stat.js b/test/simple/test-require-cache-without-stat.js
index c2c6c06..32f1ed3 100644
--- a/test/simple/test-require-cache-without-stat.js
+++ b/test/simple/test-require-cache-without-stat.js
@@ -45,20 +45,17 @@ fs.stat = function() {
};
// Load the module 'a' and 'http' once. It should become cached.
-require(common.fixturesDir + '/a');
-require('../fixtures/a.js');
-require('./../fixtures/a.js');
+require.paths.push(common.fixturesDir);
+require('a');
require('http');
console.log('counterBefore = %d', counter);
var counterBefore = counter;
-// Now load the module a bunch of times with equivalent paths.
+// Now load the module a bunch of times.
// stat should not be called.
for (var i = 0; i < 100; i++) {
- require(common.fixturesDir + '/a');
- require('../fixtures/a.js');
- require('./../fixtures/a.js');
+ require('a');
}
// Do the same with a built-in module
@@ -70,3 +67,4 @@ console.log('counterAfter = %d', counter);
var counterAfter = counter;
assert.equal(counterBefore, counterAfter);
+
--
1.7.9.msysgit.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment