2010-04-21 03:22:51 +02:00
|
|
|
/**********************************************************************/
|
|
|
|
|
|
|
|
// Module
|
|
|
|
|
2010-07-14 01:40:54 +02:00
|
|
|
|
|
|
|
// Set the environ variable NODE_MODULE_CONTEXT=1 to make node load all
|
|
|
|
// modules in thier own context.
|
|
|
|
var contextLoad = false;
|
|
|
|
if (parseInt(process.env["NODE_MODULE_CONTEXTS"]) > 0) contextLoad = true;
|
|
|
|
var Script;
|
|
|
|
|
2010-04-21 03:22:51 +02:00
|
|
|
var internalModuleCache = {};
|
|
|
|
var extensionCache = {};
|
|
|
|
|
|
|
|
function Module (id, parent) {
|
|
|
|
this.id = id;
|
|
|
|
this.exports = {};
|
|
|
|
this.parent = parent;
|
|
|
|
|
|
|
|
if (parent) {
|
|
|
|
this.moduleCache = parent.moduleCache;
|
|
|
|
} else {
|
|
|
|
this.moduleCache = {};
|
|
|
|
}
|
|
|
|
|
|
|
|
this.filename = null;
|
|
|
|
this.loaded = false;
|
|
|
|
this.exited = false;
|
|
|
|
this.children = [];
|
|
|
|
};
|
|
|
|
|
|
|
|
function createInternalModule (id, constructor) {
|
|
|
|
var m = new Module(id);
|
|
|
|
constructor(m.exports);
|
|
|
|
m.loaded = true;
|
|
|
|
internalModuleCache[id] = m;
|
|
|
|
return m;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// This contains the source code for the files in lib/
|
|
|
|
// Like, natives.fs is the contents of lib/fs.js
|
|
|
|
var natives = process.binding('natives');
|
|
|
|
|
|
|
|
function loadNative (id) {
|
|
|
|
var m = new Module(id);
|
|
|
|
internalModuleCache[id] = m;
|
|
|
|
var e = m._compile(natives[id], id);
|
|
|
|
if (e) throw e;
|
|
|
|
m.loaded = true;
|
|
|
|
return m;
|
|
|
|
}
|
2010-07-14 01:40:54 +02:00
|
|
|
|
2010-04-21 03:22:51 +02:00
|
|
|
exports.requireNative = requireNative;
|
2010-07-14 01:40:54 +02:00
|
|
|
|
2010-04-21 03:22:51 +02:00
|
|
|
function requireNative (id) {
|
|
|
|
if (internalModuleCache[id]) return internalModuleCache[id].exports;
|
|
|
|
if (!natives[id]) throw new Error('No such native module ' + id);
|
|
|
|
return loadNative(id).exports;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Event
|
|
|
|
|
|
|
|
var eventsFn = process.compile("(function (exports) {" + natives.events + "\n})",
|
|
|
|
"events");
|
|
|
|
var eventsModule = createInternalModule('events', eventsFn);
|
|
|
|
var events = eventsModule.exports;
|
|
|
|
|
|
|
|
|
|
|
|
// Modules
|
|
|
|
|
2010-05-27 02:59:55 +02:00
|
|
|
var debugLevel = parseInt(process.env["NODE_DEBUG"], 16);
|
2010-04-21 03:22:51 +02:00
|
|
|
function debug (x) {
|
2010-05-27 02:59:55 +02:00
|
|
|
if (debugLevel & 1) {
|
2010-04-21 03:22:51 +02:00
|
|
|
process.binding('stdio').writeError(x + "\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var pathFn = process.compile("(function (exports) {" + natives.path + "\n})",
|
|
|
|
"path");
|
|
|
|
var pathModule = createInternalModule('path', pathFn);
|
|
|
|
var path = pathModule.exports;
|
|
|
|
|
|
|
|
function existsSync (path) {
|
|
|
|
try {
|
|
|
|
process.binding('fs').stat(path);
|
|
|
|
return true;
|
|
|
|
} catch (e) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-07-03 06:38:06 +02:00
|
|
|
var modulePaths = [path.join(process.execPath, "..", "..", "lib", "node")];
|
2010-04-21 03:22:51 +02:00
|
|
|
|
|
|
|
if (process.env["HOME"]) {
|
|
|
|
modulePaths.unshift(path.join(process.env["HOME"], ".node_libraries"));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (process.env["NODE_PATH"]) {
|
|
|
|
modulePaths = process.env["NODE_PATH"].split(":").concat(modulePaths);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Sync unless callback given */
|
|
|
|
function findModulePath (id, dirs, callback) {
|
|
|
|
process.assert(dirs.constructor == Array);
|
|
|
|
|
|
|
|
if (/^https?:\/\//.exec(id)) {
|
|
|
|
if (callback) {
|
|
|
|
callback(id);
|
|
|
|
} else {
|
|
|
|
throw new Error("Sync http require not allowed.");
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (/\.(js|node)$/.exec(id)) {
|
|
|
|
throw new Error("No longer accepting filename extension in module names");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dirs.length == 0) {
|
|
|
|
if (callback) {
|
|
|
|
callback();
|
|
|
|
} else {
|
|
|
|
return; // sync returns null
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var dir = dirs[0];
|
|
|
|
var rest = dirs.slice(1, dirs.length);
|
|
|
|
|
|
|
|
if (id.charAt(0) == '/') {
|
|
|
|
dir = '';
|
|
|
|
rest = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
var locations = [
|
|
|
|
path.join(dir, id + ".js"),
|
|
|
|
path.join(dir, id + ".node"),
|
|
|
|
path.join(dir, id, "index.js"),
|
2010-07-20 02:54:49 +02:00
|
|
|
path.join(dir, id, "index.node"),
|
|
|
|
path.join(dir, id)
|
2010-04-21 03:22:51 +02:00
|
|
|
];
|
|
|
|
|
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
|
|
|
function searchLocations () {
|
|
|
|
var location = locations.shift();
|
|
|
|
if (!location) {
|
|
|
|
return findModulePath(id, rest, callback);
|
|
|
|
}
|
|
|
|
|
|
|
|
// if async
|
|
|
|
if (callback) {
|
|
|
|
path.exists(location, function (found) {
|
|
|
|
if (found) {
|
|
|
|
callback(location);
|
|
|
|
} else {
|
|
|
|
return searchLocations();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// if sync
|
|
|
|
} else {
|
|
|
|
if (existsSync(location)) {
|
|
|
|
return location;
|
|
|
|
} else {
|
|
|
|
return searchLocations();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return searchLocations();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// sync - no i/o performed
|
|
|
|
function resolveModulePath(request, parent) {
|
|
|
|
var id, paths;
|
|
|
|
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 parentIdPath = path.dirname(parent.id +
|
2010-07-23 09:41:28 +02:00
|
|
|
(path.basename(parent.filename).match(new RegExp('^index\\.(' + exts.join('|') + ')$')) ? "/." : ""));
|
2010-04-21 03:22:51 +02:00
|
|
|
id = path.join(parentIdPath, request);
|
2010-07-01 20:19:54 +02:00
|
|
|
// make sure require('./path') and require('path') get distinct ids, even
|
|
|
|
// when called from the toplevel js file
|
|
|
|
if (parentIdPath == '.' && ! id.match(new RegExp('/'))) {
|
|
|
|
id = './' + id;
|
|
|
|
}
|
|
|
|
debug("RELATIVE: requested:" + request + " set ID to: "+id+" from "+parent.id);
|
2010-04-21 03:22:51 +02:00
|
|
|
paths = [path.dirname(parent.filename)];
|
|
|
|
} else {
|
|
|
|
id = request;
|
|
|
|
// debug("ABSOLUTE: id="+id);
|
|
|
|
paths = modulePaths;
|
|
|
|
}
|
|
|
|
|
|
|
|
return [id, paths];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function loadModule (request, parent, callback) {
|
|
|
|
var resolvedModule = resolveModulePath(request, parent),
|
|
|
|
id = resolvedModule[0],
|
|
|
|
paths = resolvedModule[1];
|
|
|
|
|
|
|
|
debug("loadModule REQUEST " + (request) + " parent: " + parent.id);
|
|
|
|
|
Cache modules based on filename rather than ID
This is ever so slightly less efficient than caching based on ID, since the
filename has to be looked up before we can check the cache. However, it's
the most minimal approach possible to get this change in place. Since
require() is a blocking startup-time operation anyway, a bit of slowness is
not a huge problem.
A test involving require.paths modification and absolute loading. Here's the
gist of it.
Files: /p1/foo.js /p2/foo.js
1. Add "/p1" to require.paths.
2. foo1 = require("foo")
3. assert foo1 === require("/p1/foo") (fail)
4. Remove /p1 from require.paths.
5. Add /p2 to require.paths.
6. foo2 = require("foo")
7. assert foo1 !== foo2 (fail)
8. assert foo2 === require("/p2/foo") (fail)
It's an edge case, but it affects how dependencies are mapped by npm.
If your module requires foo-1.2.3, and my module requires foo-2.3.4,
then you should expect to have require("foo") give you foo-1.2.3, and
I should expect require("foo") to give me foo-2.3.4. However, with
module ID based caching, if your code loads *first*, then your "foo"
is THE "foo", so I'll get your version instead of mine.
It hasn't yet been a problem, but only because there are so few
modules, and everyone pretty much uses the latest version all the
time. But as things start to get to the 1.x and 2.x versions, it'll
be an issue, I'm sure. Dependency hell isn't fun, so this is a way to
avoid it before it strikes.
2010-07-15 19:41:40 +02:00
|
|
|
// native modules always take precedence.
|
|
|
|
var cachedNative = internalModuleCache[id];
|
|
|
|
if (cachedNative) {
|
|
|
|
return callback ? callback(null, cachedNative.exports) : cachedNative.exports;
|
|
|
|
}
|
|
|
|
if (natives[id]) {
|
|
|
|
debug('load native module ' + id);
|
|
|
|
var nativeMod = loadNative(id);
|
|
|
|
return callback ? callback(null, nativeMod.exports) : nativeMod.exports;
|
2010-04-21 03:22:51 +02:00
|
|
|
}
|
|
|
|
|
Cache modules based on filename rather than ID
This is ever so slightly less efficient than caching based on ID, since the
filename has to be looked up before we can check the cache. However, it's
the most minimal approach possible to get this change in place. Since
require() is a blocking startup-time operation anyway, a bit of slowness is
not a huge problem.
A test involving require.paths modification and absolute loading. Here's the
gist of it.
Files: /p1/foo.js /p2/foo.js
1. Add "/p1" to require.paths.
2. foo1 = require("foo")
3. assert foo1 === require("/p1/foo") (fail)
4. Remove /p1 from require.paths.
5. Add /p2 to require.paths.
6. foo2 = require("foo")
7. assert foo1 !== foo2 (fail)
8. assert foo2 === require("/p2/foo") (fail)
It's an edge case, but it affects how dependencies are mapped by npm.
If your module requires foo-1.2.3, and my module requires foo-2.3.4,
then you should expect to have require("foo") give you foo-1.2.3, and
I should expect require("foo") to give me foo-2.3.4. However, with
module ID based caching, if your code loads *first*, then your "foo"
is THE "foo", so I'll get your version instead of mine.
It hasn't yet been a problem, but only because there are so few
modules, and everyone pretty much uses the latest version all the
time. But as things start to get to the 1.x and 2.x versions, it'll
be an issue, I'm sure. Dependency hell isn't fun, so this is a way to
avoid it before it strikes.
2010-07-15 19:41:40 +02:00
|
|
|
// look up the filename first, since that's the cache key.
|
|
|
|
debug("looking for " + JSON.stringify(id) + " in " + JSON.stringify(paths));
|
|
|
|
if (!callback) {
|
|
|
|
// sync
|
|
|
|
var filename = findModulePath(request, paths);
|
|
|
|
if (!filename) {
|
|
|
|
throw new Error("Cannot find module '" + request + "'");
|
2010-04-21 03:22:51 +02:00
|
|
|
}
|
|
|
|
|
Cache modules based on filename rather than ID
This is ever so slightly less efficient than caching based on ID, since the
filename has to be looked up before we can check the cache. However, it's
the most minimal approach possible to get this change in place. Since
require() is a blocking startup-time operation anyway, a bit of slowness is
not a huge problem.
A test involving require.paths modification and absolute loading. Here's the
gist of it.
Files: /p1/foo.js /p2/foo.js
1. Add "/p1" to require.paths.
2. foo1 = require("foo")
3. assert foo1 === require("/p1/foo") (fail)
4. Remove /p1 from require.paths.
5. Add /p2 to require.paths.
6. foo2 = require("foo")
7. assert foo1 !== foo2 (fail)
8. assert foo2 === require("/p2/foo") (fail)
It's an edge case, but it affects how dependencies are mapped by npm.
If your module requires foo-1.2.3, and my module requires foo-2.3.4,
then you should expect to have require("foo") give you foo-1.2.3, and
I should expect require("foo") to give me foo-2.3.4. However, with
module ID based caching, if your code loads *first*, then your "foo"
is THE "foo", so I'll get your version instead of mine.
It hasn't yet been a problem, but only because there are so few
modules, and everyone pretty much uses the latest version all the
time. But as things start to get to the 1.x and 2.x versions, it'll
be an issue, I'm sure. Dependency hell isn't fun, so this is a way to
avoid it before it strikes.
2010-07-15 19:41:40 +02:00
|
|
|
var cachedModule = parent.moduleCache[filename];
|
|
|
|
if (cachedModule) return cachedModule.exports;
|
2010-04-21 03:22:51 +02:00
|
|
|
|
Cache modules based on filename rather than ID
This is ever so slightly less efficient than caching based on ID, since the
filename has to be looked up before we can check the cache. However, it's
the most minimal approach possible to get this change in place. Since
require() is a blocking startup-time operation anyway, a bit of slowness is
not a huge problem.
A test involving require.paths modification and absolute loading. Here's the
gist of it.
Files: /p1/foo.js /p2/foo.js
1. Add "/p1" to require.paths.
2. foo1 = require("foo")
3. assert foo1 === require("/p1/foo") (fail)
4. Remove /p1 from require.paths.
5. Add /p2 to require.paths.
6. foo2 = require("foo")
7. assert foo1 !== foo2 (fail)
8. assert foo2 === require("/p2/foo") (fail)
It's an edge case, but it affects how dependencies are mapped by npm.
If your module requires foo-1.2.3, and my module requires foo-2.3.4,
then you should expect to have require("foo") give you foo-1.2.3, and
I should expect require("foo") to give me foo-2.3.4. However, with
module ID based caching, if your code loads *first*, then your "foo"
is THE "foo", so I'll get your version instead of mine.
It hasn't yet been a problem, but only because there are so few
modules, and everyone pretty much uses the latest version all the
time. But as things start to get to the 1.x and 2.x versions, it'll
be an issue, I'm sure. Dependency hell isn't fun, so this is a way to
avoid it before it strikes.
2010-07-15 19:41:40 +02:00
|
|
|
var module = new Module(id, parent);
|
|
|
|
module.moduleCache[filename] = module;
|
|
|
|
module.loadSync(filename);
|
|
|
|
return module.exports;
|
2010-04-21 03:22:51 +02:00
|
|
|
}
|
Cache modules based on filename rather than ID
This is ever so slightly less efficient than caching based on ID, since the
filename has to be looked up before we can check the cache. However, it's
the most minimal approach possible to get this change in place. Since
require() is a blocking startup-time operation anyway, a bit of slowness is
not a huge problem.
A test involving require.paths modification and absolute loading. Here's the
gist of it.
Files: /p1/foo.js /p2/foo.js
1. Add "/p1" to require.paths.
2. foo1 = require("foo")
3. assert foo1 === require("/p1/foo") (fail)
4. Remove /p1 from require.paths.
5. Add /p2 to require.paths.
6. foo2 = require("foo")
7. assert foo1 !== foo2 (fail)
8. assert foo2 === require("/p2/foo") (fail)
It's an edge case, but it affects how dependencies are mapped by npm.
If your module requires foo-1.2.3, and my module requires foo-2.3.4,
then you should expect to have require("foo") give you foo-1.2.3, and
I should expect require("foo") to give me foo-2.3.4. However, with
module ID based caching, if your code loads *first*, then your "foo"
is THE "foo", so I'll get your version instead of mine.
It hasn't yet been a problem, but only because there are so few
modules, and everyone pretty much uses the latest version all the
time. But as things start to get to the 1.x and 2.x versions, it'll
be an issue, I'm sure. Dependency hell isn't fun, so this is a way to
avoid it before it strikes.
2010-07-15 19:41:40 +02:00
|
|
|
// async
|
|
|
|
findModulePath(request, paths, function (filename) {
|
|
|
|
if (!filename) {
|
|
|
|
var err = new Error("Cannot find module '" + request + "'");
|
|
|
|
return callback(err);
|
|
|
|
}
|
|
|
|
|
|
|
|
var cachedModule = parent.moduleCache[filename];
|
|
|
|
if (cachedModule) return callback(null, cachedModule.exports);
|
|
|
|
|
|
|
|
var module = new Module(id, parent);
|
|
|
|
module.moduleCache[filename] = module;
|
|
|
|
module.load(filename, callback);
|
|
|
|
});
|
2010-04-21 03:22:51 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// This function allows the user to register file extensions to custom
|
|
|
|
// Javascript 'compilers'. It accepts 2 arguments, where ext is a file
|
|
|
|
// extension as a string. E.g. '.coffee' for coffee-script files. compiler
|
|
|
|
// is the second argument, which is a function that gets called when the
|
|
|
|
// specified file extension is found. The compiler is passed a single
|
|
|
|
// argument, which is, the file contents, which need to be compiled.
|
|
|
|
//
|
|
|
|
// The function needs to return the compiled source, or an non-string
|
|
|
|
// variable that will get attached directly to the module exports. Example:
|
|
|
|
//
|
|
|
|
// require.registerExtension('.coffee', function(content) {
|
|
|
|
// return doCompileMagic(content);
|
|
|
|
// });
|
|
|
|
function registerExtension(ext, compiler) {
|
|
|
|
if ('string' !== typeof ext && false === /\.\w+$/.test(ext)) {
|
|
|
|
throw new Error('require.registerExtension: First argument not a valid extension string.');
|
|
|
|
}
|
|
|
|
|
|
|
|
if ('function' !== typeof compiler) {
|
|
|
|
throw new Error('require.registerExtension: Second argument not a valid compiler function.');
|
|
|
|
}
|
|
|
|
|
|
|
|
extensionCache[ext] = compiler;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Module.prototype.loadSync = function (filename) {
|
|
|
|
debug("loadSync " + JSON.stringify(filename) + " for module " + JSON.stringify(this.id));
|
|
|
|
|
|
|
|
process.assert(!this.loaded);
|
|
|
|
this.filename = filename;
|
|
|
|
|
|
|
|
if (filename.match(/\.node$/)) {
|
|
|
|
this._loadObjectSync(filename);
|
|
|
|
} else {
|
|
|
|
this._loadScriptSync(filename);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
Module.prototype.load = function (filename, callback) {
|
|
|
|
debug("load " + JSON.stringify(filename) + " for module " + JSON.stringify(this.id));
|
|
|
|
|
|
|
|
process.assert(!this.loaded);
|
|
|
|
|
|
|
|
this.filename = filename;
|
|
|
|
|
|
|
|
if (filename.match(/\.node$/)) {
|
|
|
|
this._loadObject(filename, callback);
|
|
|
|
} else {
|
|
|
|
this._loadScript(filename, callback);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
Module.prototype._loadObjectSync = function (filename) {
|
|
|
|
this.loaded = true;
|
|
|
|
process.dlopen(filename, this.exports);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
Module.prototype._loadObject = function (filename, callback) {
|
|
|
|
var self = this;
|
|
|
|
// XXX Not yet supporting loading from HTTP. would need to download the
|
|
|
|
// file, store it to tmp then run dlopen on it.
|
|
|
|
self.loaded = true;
|
|
|
|
process.dlopen(filename, self.exports); // FIXME synchronus
|
|
|
|
if (callback) callback(null, self.exports);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
function cat (id, callback) {
|
|
|
|
if (id.match(/^http:\/\//)) {
|
|
|
|
loadModule('http', process.mainModule, function (err, http) {
|
|
|
|
if (err) {
|
|
|
|
if (callback) callback(err);
|
|
|
|
} else {
|
|
|
|
http.cat(id, callback);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
} else {
|
2010-05-07 07:03:43 +02:00
|
|
|
requireNative('fs').readFile(id, 'utf8', callback);
|
2010-04-21 03:22:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Returns exception if any
|
|
|
|
Module.prototype._compile = function (content, filename) {
|
|
|
|
var self = this;
|
|
|
|
// remove shebang
|
|
|
|
content = content.replace(/^\#\!.*/, '');
|
|
|
|
|
|
|
|
// Compile content if needed
|
|
|
|
var ext = path.extname(filename);
|
|
|
|
if (extensionCache[ext]) {
|
|
|
|
content = extensionCache[ext](content);
|
|
|
|
}
|
|
|
|
|
|
|
|
function requireAsync (url, cb) {
|
|
|
|
loadModule(url, self, cb);
|
|
|
|
}
|
|
|
|
|
|
|
|
function require (path) {
|
|
|
|
return loadModule(path, self);
|
|
|
|
}
|
|
|
|
|
|
|
|
require.paths = modulePaths;
|
|
|
|
require.async = requireAsync;
|
|
|
|
require.main = process.mainModule;
|
|
|
|
require.registerExtension = registerExtension;
|
|
|
|
|
2010-07-14 01:40:54 +02:00
|
|
|
var dirname = path.dirname(filename);
|
|
|
|
|
|
|
|
if (contextLoad) {
|
|
|
|
if (!Script) Script = Script = process.binding('evals').Script;
|
|
|
|
|
|
|
|
if (self.id !== ".") {
|
|
|
|
debug('load submodule');
|
|
|
|
// not root module
|
|
|
|
var sandbox = {};
|
|
|
|
for (var k in global) {
|
|
|
|
sandbox[k] = global[k];
|
|
|
|
}
|
|
|
|
sandbox.require = require;
|
|
|
|
sandbox.exports = self.exports;
|
|
|
|
sandbox.__filename = filename;
|
|
|
|
sandbox.__dirname = dirname;
|
|
|
|
sandbox.module = self;
|
2010-07-15 19:52:31 +02:00
|
|
|
sandbox.root = global;
|
2010-07-14 01:40:54 +02:00
|
|
|
|
|
|
|
Script.runInNewContext(content, sandbox, filename);
|
2010-04-21 03:22:51 +02:00
|
|
|
|
2010-07-14 01:40:54 +02:00
|
|
|
} else {
|
|
|
|
debug('load root module');
|
|
|
|
// root module
|
|
|
|
global.require = require;
|
|
|
|
global.exports = self.exports;
|
|
|
|
global.__filename = filename;
|
|
|
|
global.__dirname = dirname;
|
|
|
|
global.module = self;
|
2010-07-14 23:22:58 +02:00
|
|
|
global.root = global;
|
2010-07-14 01:40:54 +02:00
|
|
|
Script.runInThisContext(content, filename);
|
|
|
|
}
|
2010-04-21 03:22:51 +02:00
|
|
|
|
|
|
|
} else {
|
2010-07-14 01:40:54 +02:00
|
|
|
if ('string' === typeof content) {
|
|
|
|
// create wrapper function
|
|
|
|
var wrapper = "(function (exports, require, module, __filename, __dirname) { "
|
|
|
|
+ content
|
|
|
|
+ "\n});";
|
|
|
|
|
|
|
|
var compiledWrapper = process.compile(wrapper, filename);
|
2010-07-28 05:36:58 +02:00
|
|
|
if (filename === process.argv[1]) process.checkBreak();
|
2010-07-14 01:40:54 +02:00
|
|
|
compiledWrapper.apply(self.exports, [self.exports, require, self, filename, dirname]);
|
|
|
|
} else {
|
|
|
|
self.exports = content;
|
|
|
|
}
|
2010-04-21 03:22:51 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
Module.prototype._loadScriptSync = function (filename) {
|
2010-05-29 22:38:00 +02:00
|
|
|
var content = requireNative('fs').readFileSync(filename, 'utf8');
|
2010-06-03 12:39:12 +02:00
|
|
|
this._compile(content, filename);
|
|
|
|
this.loaded = true;
|
2010-04-21 03:22:51 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
Module.prototype._loadScript = function (filename, callback) {
|
|
|
|
var self = this;
|
|
|
|
cat(filename, function (err, content) {
|
|
|
|
debug('cat done');
|
|
|
|
if (err) {
|
|
|
|
if (callback) callback(err);
|
|
|
|
} else {
|
2010-06-03 12:39:12 +02:00
|
|
|
try {
|
|
|
|
self._compile(content, filename);
|
|
|
|
} catch (err) {
|
|
|
|
if (callback) callback(err);
|
|
|
|
return;
|
2010-04-21 03:22:51 +02:00
|
|
|
}
|
2010-06-03 12:39:12 +02:00
|
|
|
|
|
|
|
self._waitChildrenLoad(function () {
|
|
|
|
self.loaded = true;
|
|
|
|
if (self.onload) self.onload();
|
|
|
|
if (callback) callback(null, self.exports);
|
|
|
|
});
|
2010-04-21 03:22:51 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
Module.prototype._waitChildrenLoad = function (callback) {
|
|
|
|
var nloaded = 0;
|
|
|
|
var children = this.children;
|
|
|
|
for (var i = 0; i < children.length; i++) {
|
|
|
|
var child = children[i];
|
|
|
|
if (child.loaded) {
|
|
|
|
nloaded++;
|
|
|
|
} else {
|
|
|
|
child.onload = function () {
|
|
|
|
child.onload = null;
|
|
|
|
nloaded++;
|
|
|
|
if (children.length == nloaded && callback) callback();
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (children.length == nloaded && callback) callback();
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// bootstrap main module.
|
2010-07-01 20:10:22 +02:00
|
|
|
exports.runMain = function () {
|
2010-04-21 03:22:51 +02:00
|
|
|
|
|
|
|
// Load the main module--the command line argument.
|
|
|
|
process.mainModule = new Module(".");
|
2010-07-01 20:10:22 +02:00
|
|
|
process.mainModule.loadSync(process.argv[1]);
|
2010-04-21 03:22:51 +02:00
|
|
|
}
|