Absolute path names for require() refer to node.libraryPaths
This commit is contained in:
parent
5ddc4f5d0c
commit
c8b143bf30
200
src/node.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
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");
|
||||
};
|
||||
|
@ -1,6 +1,9 @@
|
||||
node.debug("load fixtures/a.js");
|
||||
|
||||
var c = require("b/c.js");
|
||||
var string = "A";
|
||||
|
||||
|
||||
exports.A = function () {
|
||||
return string;
|
||||
};
|
||||
|
@ -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");
|
||||
});
|
||||
|
@ -1,3 +1,5 @@
|
||||
node.debug("load fixtures/b/d.js");
|
||||
|
||||
var string = "D";
|
||||
|
||||
exports.D = function () {
|
||||
|
@ -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…
x
Reference in New Issue
Block a user