Skip to content

Commit

Permalink
never return broken modules from require
Browse files Browse the repository at this point in the history
  • Loading branch information
ef4 committed Jun 24, 2016
1 parent af9c05d commit d3dea19
Showing 1 changed file with 32 additions and 6 deletions.
38 changes: 32 additions & 6 deletions lib/loader/loader.js
Expand Up @@ -90,10 +90,21 @@ var loader, define, requireModule, require, requirejs;
this.deps = !deps.length && callback.length ? defaultDeps : deps;
this.module = { exports: {} };
this.callback = callback;
this.state = 'new';
this.hasExportsAsDep = false;
this.isAlias = alias;
this.reified = new Array(deps.length);

/*
Each module normally passes through these states, in order:
new : initial state
pending : this module is scheduled to be executed
reifying : this module's dependencies are being executed
reified : this module's dependencies finished executing successfully
errored : this module's dependencies failed to execute
finalized : this module executed successfully
*/
this.state = 'new';

}

Module.prototype.makeDefaultExport = function() {
Expand All @@ -106,18 +117,19 @@ var loader, define, requireModule, require, requirejs;
};

Module.prototype.exports = function() {
if (this.state === 'finalized') { return this.module.exports; }
// if finalized, there is no work to do. If reifying, there is a
// circular dependency so we must return our (partial) exports.
if (this.state === 'finalized' || this.state === 'reifying') { return this.module.exports; }
stats.exports++;

this.state = 'finalized';

if (loader.wrapModules) {
this.callback = loader.wrapModules(this.name, this.callback);
}

this.reify();

var result = this.callback.apply(this, this.reified);
this.state = 'finalized';

if (!(this.hasExportsAsDep && result === undefined)) {
this.module.exports = result;
Expand All @@ -132,12 +144,26 @@ var loader, define, requireModule, require, requirejs;
};

Module.prototype.reify = function() {
if (this.state === 'reified') { return; }
this.state = 'reifying';
try {
this.reified = this._reify();
this.state = 'reified';
} finally {
if (this.state === 'reifying') {
this.state = 'errored';
}
}
};

Module.prototype._reify = function() {
stats.reify++;
var reified = this.reified;
var reified = this.reified.slice();
for (var i = 0; i < reified.length; i++) {
var mod = reified[i];
reified[i] = mod.exports ? mod.exports : mod.module.exports();
}
return reified;
};

Module.prototype.findDeps = function(pending) {
Expand Down Expand Up @@ -223,7 +249,7 @@ var loader, define, requireModule, require, requirejs;

if (!mod) { missingModule(name, referrer); }

if (pending && mod.state === 'new') {
if (pending && mod.state !== 'pending' && mod.state !== 'finalized') {
mod.findDeps(pending);
pending.push(mod);
stats.pendingQueueLength++;
Expand Down

0 comments on commit d3dea19

Please sign in to comment.