Browse Source

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

v0.7.4-release
Ryan Dahl 15 years ago
parent
commit
c8b143bf30
  1. 200
      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

200
src/node.js

@ -71,6 +71,16 @@ clearInterval = clearTimeout;
// 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 = [];
function require_async (url) {
@ -83,30 +93,25 @@ function require (url) {
}
function include_async (url) {
var currentModule = node.loadingModules[0];
return currentModule.newChild(url, currentModule.target);
var promise = require_async(url)
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) {
include_async(url).wait();
}
node.Module = function (o) {
this.parent = o.parent;
this.target = o.target || {};
if (!o.path) throw "path argument required";
if (o.path.charAt(0) == "/") {
throw "Absolute module paths are not yet supported by Node";
}
if (o.path.match(/:\/\//)) {
this.filename = o.path;
} else {
var dir = o.base_directory || ".";
this.filename = node.path.join(dir, o.path);
}
node.Module = function (filename, parent) {
node.assert(filename.charAt(0) == "/");
this.filename = filename;
this.target = {};
this.parent = parent;
this.loaded = false;
this.loadPromise = null;
@ -114,18 +119,99 @@ node.Module = function (o) {
this.children = [];
};
node.Module.prototype.load = function (callback) {
node.Module.cache = {};
(function () {
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);
}
}
function findPath (path, dirs, callback) {
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 {
findPath(path, rest, callback);
}
});
}
}
node.loadModule = function (requestedPath, target, parent) {
var loadPromise = new node.Promise();
// 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;
if (this.filename.match(/\.node$/)) {
return this.loadObject(callback);
this.loadObject(loadPromise);
} else {
return this.loadScript(callback);
this.loadScript(loadPromise);
}
};
node.Module.prototype.loadObject = function (callback) {
node.Module.prototype.loadObject = function (loadPromise) {
var self = this;
var loadPromise = new node.Promise();
self.loadPromise = loadPromise;
// XXX Not yet supporting loading from HTTP. would need to download the
// file, store it to tmp then run dlopen on it.
node.fs.exists(self.filename, function (does_exist) {
@ -139,57 +225,28 @@ node.Module.prototype.loadObject = function (callback) {
node.exit(1);
}
});
return loadPromise;
};
node.Module.prototype.loadScript = function (callback) {
node.Module.prototype.loadScript = function (loadPromise) {
var self = this;
if (self.loaded) {
throw "Module '" + self.filename + "' is already loaded.";
}
var catPromise = node.cat(self.filename);
var loadPromise = new node.Promise();
node.assert(self.loadPromise === null);
self.loadPromise = loadPromise;
var cat_promise = node.cat(self.filename);
cat_promise.addErrback(function () {
node.stdio.writeError("Error reading " + self.filename + "\n");
loadPromise.emitError();
node.exit(1);
catPromise.addErrback(function () {
loadPromise.emitError(new Error("Error reading " + self.filename + "\n"));
});
cat_promise.addCallback(function (content) {
catPromise.addCallback(function (content) {
// remove shebang
content = content.replace(/^\#\!.*/, '');
// create wrapper function
var wrapper = "function (__filename) { "+
" var onLoad; "+
" var onExit; "+
" var exports = this; "+
content+
"\n"+
" this.__onLoad = onLoad;\n"+
" this.__onExit = onExit;\n"+
"};\n";
var wrapper = "function (__filename, exports) { " + content + "\n};";
var compiled_wrapper = node.compile(wrapper, self.filename);
node.loadingModules.unshift(self);
compiled_wrapper.apply(self.target, [self.filename]);
compiled_wrapper.apply(self.target, [self.filename, self.target]);
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.loaded = true;
loadPromise.emitSuccess(self.target);
@ -198,15 +255,7 @@ node.Module.prototype.loadScript = function (callback) {
};
node.Module.prototype.newChild = function (path, target) {
var child = new node.Module({
target: target,
path: path,
base_directory: node.path.dirname(this.filename),
parent: this
});
this.children.push(child);
child.load();
return child.loadPromise;
return node.loadModule(path, target, this);
};
node.Module.prototype.waitChildrenLoad = function (callback) {
@ -227,22 +276,19 @@ node.Module.prototype.waitChildrenLoad = function (callback) {
};
(function () {
var cwd = node.cwd();
// Make ARGV[0] and ARGV[1] into full paths.
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) != "/") {
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.
var root_module = new node.Module({
path: node.path.filename(ARGV[1]),
base_directory: node.path.dirname(ARGV[1]),
target: this
});
root_module.load();
node.loadModule(ARGV[1], process);
node.exit = function (code) {
process.emit("exit");

14
src/util.js

@ -92,17 +92,23 @@ node.path = new function () {
};
print = function (x) {
return node.stdio.write(x);
node.stdio.write(x);
};
puts = function (x) {
return print(x.toString() + "\n");
print(x.toString() + "\n");
};
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) {
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 string = "A";
exports.A = function () {
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 string = "C";
@ -12,4 +14,5 @@ exports.D = function () {
process.addListener("exit", function () {
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";
exports.D = function () {

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

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

Loading…
Cancel
Save