tc39 / proposal-dynamic-import

import() proposal for JavaScript

Home Page:https://tc39.github.io/proposal-dynamic-import/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

importModule function in README does not work

hax opened this issue · comments

https://github.com/tc39/proposal-dynamic-import#using-host-specific-mechanisms

function importModule(url) {
  return new Promise((resolve, reject) => {
    const script = document.createElement("script");
    const tempGlobal = "__tempModuleLoadingVariable" + Math.random().toString(32).substring(2);
    script.type = "module";
    script.textContent = `import * as m from "${url}"; window.${tempGlobal} = m;`;

    script.onload = () => {
      resolve(window[tempGlobal]);
      delete window[tempGlobal];
      script.remove();
    };

    script.onerror = () => {
      reject(new Error("Failed to load module script with URL " + url));
      delete window[tempGlobal];
      script.remove();
    };

    document.documentElement.appendChild(script);
  });
}

This importModule function does not work, because a inline script without src attribute will never trigger load event.

commented

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)