Browse Source

Simplified module system

createModule got removed as it was unnecessary and caused issues by
doing its own cache checks independent of loadModule. Internal modules
are now the only globally cached modules, all other modules are only
cached by inheriting their parent modules cache.

Credits: Module specific cache and a few other diffs by Blaine Cook

431662d25c
http://romeda.org/blog/2010/01/hot-code-loading-in-nodejs.html
http://thread.gmane.org/gmane.comp.lang.javascript.nodejs/1994
v0.7.4-release
Felix Geisendörfer 15 years ago
committed by Ryan Dahl
parent
commit
b73f61a137
  1. 55
      src/node.js
  2. 1
      test/mjsunit/test-module-loading.js

55
src/node.js

@ -41,11 +41,20 @@ node.dns.createConnection = removed("node.dns.createConnection() has moved. Use
// Module
var internalModuleCache = {};
function Module (id, parent) {
this.id = id;
this.exports = {};
this.parent = parent;
this.moduleCache = {};
if (parent) {
process.mixin(this.moduleCache, parent.moduleCache);
this.moduleCache[parent.id] = parent;
}
this.filename = null;
this.loaded = false;
this.loadPromise = null;
@ -53,23 +62,11 @@ function Module (id, parent) {
this.children = [];
};
var moduleCache = {};
function createModule (id, parent) {
if (id in moduleCache) {
debug("found " + JSON.stringify(id) + " in cache");
return moduleCache[id];
}
debug("didn't found " + JSON.stringify(id) + " in cache. creating new module");
var m = new Module(id, parent);
moduleCache[id] = m;
return m;
};
function createInternalModule (id, constructor) {
var m = createModule(id);
var m = new Module(id);
constructor(m.exports);
m.loaded = true;
internalModuleCache[id] = m;
return m;
};
@ -803,11 +800,7 @@ function findModulePath (id, dirs, callback) {
searchLocations();
}
function loadModule (request, parent) {
// This is the promise which is actually returned from require.async()
var loadPromise = new events.Promise();
// debug("loadModule REQUEST " + (request) + " parent: " + JSON.stringify(parent));
function resolveModulePath(request, parent) {
var id, paths;
if (request.charAt(0) == "." && (request.charAt(1) == "/" || request.charAt(1) == ".")) {
@ -823,12 +816,24 @@ function loadModule (request, parent) {
paths = process.paths;
}
if (id in moduleCache) {
return [id, paths];
}
function loadModule (request, parent) {
var
// The promise returned from require.async()
loadPromise = new events.Promise(),
resolvedModule = resolveModulePath(request, parent),
id = resolvedModule[0],
paths = resolvedModule[1];
// debug("loadModule REQUEST " + (request) + " parent: " + JSON.stringify(parent));
var cachedModule = internalModuleCache[id] || parent.moduleCache[id];
if (cachedModule) {
debug("found " + JSON.stringify(id) + " in cache");
// In cache
var module = moduleCache[id];
process.nextTick(function() {
loadPromise.emitSuccess(module.exports);
loadPromise.emitSuccess(cachedModule.exports);
});
} else {
debug("looking for " + JSON.stringify(id) + " in " + JSON.stringify(paths));
@ -837,7 +842,7 @@ function loadModule (request, parent) {
if (!filename) {
loadPromise.emitError(new Error("Cannot find module '" + request + "'"));
} else {
var module = createModule(id, parent);
var module = new Module(id, parent);
module.load(filename, loadPromise);
}
});
@ -978,7 +983,7 @@ if (process.argv[1].charAt(0) != "/" && !(/^http:\/\//).exec(process.argv[1])) {
}
// Load the main module--the command line argument.
process.mainModule = createModule(".");
process.mainModule = new Module(".");
var loadPromise = new events.Promise();
process.mainModule.load(process.argv[1], loadPromise);

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

@ -41,7 +41,6 @@ assert.notEqual(one.hello, two.hello);
debug("test cycles containing a .. path");
var root = require("./fixtures/cycles/root"),
foo = require("./fixtures/cycles/folder/foo");
assert.equal(root.foo, foo);
assert.equal(root.sayHello(), root.hello);
var errorThrown = false;

Loading…
Cancel
Save