-
Notifications
You must be signed in to change notification settings - Fork 115
Lazy circular dependencies no longer work #105
Description
It looks like the changes that were part of #92 broke lazy circular dependencies. After investigating I found this to be the cause for #104
Lazy circular dependencies work with Node.js and other CommonJS module loaders/bundlers. I think it is important to maintain parity with the Node.js CommonJS module loader since this is breaking at least one library.
Given the following contrived setup where ./a.js lazily requires ./b.js and ./b.js requires ./a.js:
_./a.js:_
setTimeout(function() {
var b = require('./b'); // ** Lazily require './b.js' inside `setTimeout()` callback **
console.log(b);
}, 10);
module.exports = 'SUCCESS!';_./b.js:_
module.exports = require('./a');Running the following code under Node.js using node ./a.js will result in the following output:
SUCCESS!
However, running the code bundled up by rollup will output undefined.
Problem
Rollup produces the following code that eagerly loads each module:
(function() {
'use strict';
function createCommonjsModule(fn, module) {
return module = {
exports: {}
}, fn(module, module.exports), module.exports;
}
var b = createCommonjsModule(function(module) {
module.exports = a; // ** a is undefined at this point **
});
var a = createCommonjsModule(function(module) {
setTimeout(function() {
var b$$1 = b;
console.log(b$$1);
}, 10);
module.exports = 'SUCCESS!';
});
}());Proposed solution
I propose that this plugin be updated to produce output code similar to the following:
(function() {
'use strict';
function defineCommonjsModule(fn) {
var module = {
exports: {}
};
var loaded;
return function require() {
if (!loaded) {
loaded = true;
fn(module, module.exports);
}
return module.exports;
};
}
var $$require_b = defineCommonjsModule(function(module, exports) {
module.exports = $$require_a();
});
var $$require_a = defineCommonjsModule(function(module, exports) {
setTimeout(function() {
var b = $$require_b();
console.log(b);
}, 10);
module.exports = 'SUCCESS!';
});
$$require_a(); // ** Load the entry module **
}());As a side benefit, the proposed code will be closer to the user's code while still being very concise and efficient.
Thoughts?
/cc @Rich-Harris @lohfu