Closed caspervonb closed 9 years ago
This is all about the prelude, it was never built for this kind of hackery.
--full-paths
, which gives us a stable identifier.So, accounting for all that, we'll end up with a prelude template that looks something like the following
(function(cache, entries) {
function require(name) {
if (cache[name]) {
return cache[name].exports;
}
var modules = <%= modules %>
if(!modules[name]) {
var error = new Error('Cannot find module \'' + name + '\'');
throw error;
}
function resolve(name) {
return <%= resolves %>[name];
}
var module = {
locals: {},
exports: {},
identities: {},
exec: function(id, fn) {
if (!module.identities[id]) {
module.identities[id] = fn;
fn();
}
},
};
cache[name] = module;
var fn = modules[name].bind(module.exports, function(key) {
var identifiers = resolve(name);
if (identifiers && identifiers[key]) {
return require(identifiers[key]);
}
return require(key);
}, module, module.exports);
fn();
var source = modules[name].toString();
addEventListener('patch', function() {
if (source !== modules[name].toString()) {
fn();
}
source = modules[name].toString();
});
}
entries.forEach(require);
return require;
}(%= arguments %));
Fixed in 209c550c72b2c02c7d38bb8dca22ee97b814461c
Reopening this, while new requires do work with the previously mentioned commit, they can break on huge modules.
Minimal reproducible example, with the transform and eval functionality disabled.
setInterval(function() {
// var lib = require('util');
console.log(typeof lib);
});
Uncommenting that require will cause a detached state. However if the module is a small module without many dependencies being pulled in, it is fine.
So it seems this is not a problem inherent to the prelude. Also callbacks are the only things that are breaking, so its not straight out failing its just failing to keep the binding. In #2 the cause appeared to be that the closure was changing I can't see that being the case here.
Now, adding a big chunk of things in another scope, does not appear to break anything, same goes for removing.
Breakthrough, the following form seems to to work, in the case case i was adding 30k lines of extra modules.
var modules = {};
function require(id) {
apply(modules);
return modules[id]();
}
function apply(modules) {
if (!modules['a']) {
(function() {
modules['a'] = function() {
setInterval(function() {
document.body.innerHTML = 'Are we live?';
}, 500);
};
}());
}
}
require('a');
Details to come.