Open hax opened 6 years ago
Version that does not use onload
:
function importModule(url) {
// escape characters that are used to delimit the module URL.
// this way the following module works: 'data:text/javascript,console.log("hello")'
url = url.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
return new Promise((resolve, reject) => {
const script = document.createElement("script");
const tempGlobal = "__tempModuleLoadingVariable" + Math.random().toString(32).substring(2);
function cleanup() {
delete window[tempGlobal];
script.remove();
}
window[tempGlobal] = function (module) {
cleanup();
resolve(module);
};
script.type = "module";
script.textContent = `import * as m from "${url}"; window.${tempGlobal}(m);`;
script.onerror = () => {
reject(new Error("Failed to load module script with URL " + url));
cleanup();
};
document.documentElement.appendChild(script);
});
}
Note that the returned promise does not reject when the module identifier is not valid (eg importModule('')
), couldn't get that to work (it stays stuck in a pending state)
https://github.com/tc39/proposal-dynamic-import#using-host-specific-mechanisms
This
importModule
function does not work, because a inline script withoutsrc
attribute will never triggerload
event.