Browse Source

Absolute path names for require() refer to node.libraryPaths

v0.7.4-release
Ryan Dahl 15 years ago
parent
commit
c8b143bf30
  1. 196
      src/node.js
  2. 14
      src/util.js
  3. 0
      test/mjsunit/disabled/test-remote-module-loading.js
  4. 3
      test/mjsunit/fixtures/a.js
  5. 3
      test/mjsunit/fixtures/b/c.js
  6. 2
      test/mjsunit/fixtures/b/d.js
  7. 3
      test/mjsunit/test-module-loading.js

196
src/node.js

@ -71,6 +71,16 @@ clearInterval = clearTimeout;
// Module // Module
node.libraryPaths = [ node.path.join(ENV["HOME"], ".node_libraries")
, node.path.join(node.installPrefix, "lib/node_libraries")
, "/"
];
if (ENV["NODE_LIBRARY_PATHS"]) {
node.libraryPaths =
ENV["NODE_LIBRARY_PATHS"].split(":").concat(node.libraryPaths);
}
node.loadingModules = []; node.loadingModules = [];
function require_async (url) { function require_async (url) {
@ -83,49 +93,125 @@ function require (url) {
} }
function include_async (url) { function include_async (url) {
var currentModule = node.loadingModules[0]; var promise = require_async(url)
return currentModule.newChild(url, currentModule.target); promise.addCallback(function (t) {
// copy properties into global namespace.
for (var prop in t) {
if (t.hasOwnProperty(prop)) process[prop] = t[prop];
}
});
return promise;
} }
function include (url) { function include (url) {
include_async(url).wait(); include_async(url).wait();
} }
node.Module = function (o) { node.Module = function (filename, parent) {
this.parent = o.parent; node.assert(filename.charAt(0) == "/");
this.target = o.target || {}; this.filename = filename;
this.target = {};
this.parent = parent;
if (!o.path) throw "path argument required"; this.loaded = false;
this.loadPromise = null;
this.exited = false;
this.children = [];
};
node.Module.cache = {};
if (o.path.charAt(0) == "/") { (function () {
throw "Absolute module paths are not yet supported by Node"; function retrieveFromCache (loadPromise, fullPath, parent) {
var module;
if (fullPath in node.Module.cache) {
module = node.Module.cache[fullPath];
setTimeout(function () {
loadPromise.emitSuccess(module.target);
}, 0);
} else {
module = new node.Module(fullPath, parent);
node.Module.cache[fullPath] = module;
module.load(loadPromise);
}
} }
if (o.path.match(/:\/\//)) { function findPath (path, dirs, callback) {
this.filename = o.path; node.assert(path.charAt(0) == "/");
node.assert(dirs.constructor == Array);
if (dirs.length == 0) {
callback();
} else {
var dir = dirs[0];
var rest = dirs.slice(1, dirs.length);
var fullPath = node.path.join(dir, path);
node.fs.exists(fullPath, function (doesExist) {
if (doesExist) {
callback(fullPath);
} else { } else {
var dir = o.base_directory || "."; findPath(path, rest, callback);
this.filename = node.path.join(dir, o.path); }
});
}
} }
this.loaded = false; node.loadModule = function (requestedPath, target, parent) {
this.loadPromise = null; var loadPromise = new node.Promise();
this.exited = false;
this.children = []; // On success copy the loaded properties into the target
loadPromise.addCallback(function (t) {
for (var prop in t) {
if (t.hasOwnProperty(prop)) target[prop] = t[prop];
}
});
if (!parent) {
// root module
node.assert(requestedPath.charAt(0) == "/");
retrieveFromCache(loadPromise, requestedPath);
} else {
if (requestedPath.charAt(0) == "/") {
// Need to find the module in node.libraryPaths
findPath(requestedPath, node.libraryPaths, function (fullPath) {
if (fullPath) {
retrieveFromCache(loadPromise, fullPath, parent);
} else {
loadPromise.emitError();
}
});
} else {
// Relative file load
var fullPath = node.path.join(node.path.dirname(parent.filename),
requestedPath);
retrieveFromCache(loadPromise, fullPath, parent);
}
}
return loadPromise;
}; };
}());
node.Module.prototype.load = function (loadPromise) {
if (this.loaded) {
loadPromise.emitError(new Error("Module '" + self.filename + "' is already loaded."));
return;
}
node.assert(!node.loadPromise);
this.loadPromise = loadPromise;
node.Module.prototype.load = function (callback) {
if (this.filename.match(/\.node$/)) { if (this.filename.match(/\.node$/)) {
return this.loadObject(callback); this.loadObject(loadPromise);
} else { } else {
return this.loadScript(callback); this.loadScript(loadPromise);
} }
}; };
node.Module.prototype.loadObject = function (callback) { node.Module.prototype.loadObject = function (loadPromise) {
var self = this; var self = this;
var loadPromise = new node.Promise();
self.loadPromise = loadPromise;
// XXX Not yet supporting loading from HTTP. would need to download the // XXX Not yet supporting loading from HTTP. would need to download the
// file, store it to tmp then run dlopen on it. // file, store it to tmp then run dlopen on it.
node.fs.exists(self.filename, function (does_exist) { node.fs.exists(self.filename, function (does_exist) {
@ -139,57 +225,28 @@ node.Module.prototype.loadObject = function (callback) {
node.exit(1); node.exit(1);
} }
}); });
return loadPromise;
}; };
node.Module.prototype.loadScript = function (callback) { node.Module.prototype.loadScript = function (loadPromise) {
var self = this; var self = this;
if (self.loaded) { var catPromise = node.cat(self.filename);
throw "Module '" + self.filename + "' is already loaded.";
}
var loadPromise = new node.Promise();
node.assert(self.loadPromise === null);
self.loadPromise = loadPromise;
var cat_promise = node.cat(self.filename);
cat_promise.addErrback(function () { catPromise.addErrback(function () {
node.stdio.writeError("Error reading " + self.filename + "\n"); loadPromise.emitError(new Error("Error reading " + self.filename + "\n"));
loadPromise.emitError();
node.exit(1);
}); });
cat_promise.addCallback(function (content) { catPromise.addCallback(function (content) {
// remove shebang // remove shebang
content = content.replace(/^\#\!.*/, ''); content = content.replace(/^\#\!.*/, '');
// create wrapper function // create wrapper function
var wrapper = "function (__filename) { "+ var wrapper = "function (__filename, exports) { " + content + "\n};";
" var onLoad; "+
" var onExit; "+
" var exports = this; "+
content+
"\n"+
" this.__onLoad = onLoad;\n"+
" this.__onExit = onExit;\n"+
"};\n";
var compiled_wrapper = node.compile(wrapper, self.filename); var compiled_wrapper = node.compile(wrapper, self.filename);
node.loadingModules.unshift(self); node.loadingModules.unshift(self);
compiled_wrapper.apply(self.target, [self.filename]); compiled_wrapper.apply(self.target, [self.filename, self.target]);
node.loadingModules.shift(); node.loadingModules.shift();
self.onLoad = self.target.__onLoad;
self.onExit = self.target.__onExit;
if (self.onLoad || self.onExit) {
node.stdio.writeError( "(node) onLoad and onExit have been removed. "
+ " module load is synchronous so onLoad is unnecessary"
+ " Use process.addListener('exit') for onExit. "
);
node.exit(1);
}
self.waitChildrenLoad(function () { self.waitChildrenLoad(function () {
self.loaded = true; self.loaded = true;
loadPromise.emitSuccess(self.target); loadPromise.emitSuccess(self.target);
@ -198,15 +255,7 @@ node.Module.prototype.loadScript = function (callback) {
}; };
node.Module.prototype.newChild = function (path, target) { node.Module.prototype.newChild = function (path, target) {
var child = new node.Module({ return node.loadModule(path, target, this);
target: target,
path: path,
base_directory: node.path.dirname(this.filename),
parent: this
});
this.children.push(child);
child.load();
return child.loadPromise;
}; };
node.Module.prototype.waitChildrenLoad = function (callback) { node.Module.prototype.waitChildrenLoad = function (callback) {
@ -227,22 +276,19 @@ node.Module.prototype.waitChildrenLoad = function (callback) {
}; };
(function () { (function () {
var cwd = node.cwd();
// Make ARGV[0] and ARGV[1] into full paths. // Make ARGV[0] and ARGV[1] into full paths.
if (ARGV[0].charAt(0) != "/") { if (ARGV[0].charAt(0) != "/") {
ARGV[0] = node.path.join(node.cwd(), ARGV[0]); ARGV[0] = node.path.join(cwd, ARGV[0]);
} }
if (ARGV[1].charAt(0) != "/") { if (ARGV[1].charAt(0) != "/") {
ARGV[1] = node.path.join(node.cwd(), ARGV[1]); ARGV[1] = node.path.join(cwd, ARGV[1]);
} }
// Load the root module--the command line argument. // Load the root module--the command line argument.
var root_module = new node.Module({ node.loadModule(ARGV[1], process);
path: node.path.filename(ARGV[1]),
base_directory: node.path.dirname(ARGV[1]),
target: this
});
root_module.load();
node.exit = function (code) { node.exit = function (code) {
process.emit("exit"); process.emit("exit");

14
src/util.js

@ -92,17 +92,23 @@ node.path = new function () {
}; };
print = function (x) { print = function (x) {
return node.stdio.write(x); node.stdio.write(x);
}; };
puts = function (x) { puts = function (x) {
return print(x.toString() + "\n"); print(x.toString() + "\n");
}; };
p = function (x) { p = function (x) {
return puts(JSON.stringify(x)); if (x === null) {
puts("null");
} else if (x === NaN) {
puts("NaN");
} else {
puts(JSON.stringify(x) || "undefined");
}
}; };
node.debug = function (x) { node.debug = function (x) {
return node.stdio.writeError("DEBUG: " + x.toString() + "\n"); node.stdio.writeError("DEBUG: " + x.toString() + "\n");
}; };

0
test/mjsunit/test-remote-module-loading.js → test/mjsunit/disabled/test-remote-module-loading.js

3
test/mjsunit/fixtures/a.js

@ -1,6 +1,9 @@
node.debug("load fixtures/a.js");
var c = require("b/c.js"); var c = require("b/c.js");
var string = "A"; var string = "A";
exports.A = function () { exports.A = function () {
return string; return string;
}; };

3
test/mjsunit/fixtures/b/c.js

@ -1,3 +1,5 @@
node.debug("load fixtures/b/c.js");
var d = require("d.js"); var d = require("d.js");
var string = "C"; var string = "C";
@ -12,4 +14,5 @@ exports.D = function () {
process.addListener("exit", function () { process.addListener("exit", function () {
string = "C done"; string = "C done";
puts("b/c.js exit");
}); });

2
test/mjsunit/fixtures/b/d.js

@ -1,3 +1,5 @@
node.debug("load fixtures/b/d.js");
var string = "D"; var string = "D";
exports.D = function () { exports.D = function () {

3
test/mjsunit/test-module-loading.js

@ -1,3 +1,4 @@
node.debug("load test-module-loading.js");
include("mjsunit.js"); include("mjsunit.js");
var a = require("fixtures/a.js"); var a = require("fixtures/a.js");
var d = require("fixtures/b/d.js"); var d = require("fixtures/b/d.js");
@ -35,4 +36,6 @@ process.addListener("exit", function () {
assertInstanceof(d2.D, Function); assertInstanceof(d2.D, Function);
assertEquals("D done", d2.D()); assertEquals("D done", d2.D());
puts("exit");
}); });

Loading…
Cancel
Save