maoberlehner / distributed-vue-applications-loading-components-via-http

This is an example project for the following article: https://markus.oberlehner.net/blog/distributed-vue-applications-loading-components-via-http/
49 stars 14 forks source link

Chaining cycle detected? #4

Open DC240 opened 3 years ago

DC240 commented 3 years ago

I'm getting the following error message whenever I try to load a file using the externalComponent function (at line 11):

TypeError: Chaining cycle detected for promise #<Promise>

This my slightly edited version of the function:

export default async function externalComponent (url) {
  const name = url.split('/').reverse()[0].match(/^(.*?)\.js/)[1];

  if (window[name]) return window[name];

  window[name] = new Promise((resolve, reject) => {
    const script = document.createElement('script');
    script.async = true;
    script.type = "module";
    script.addEventListener('load', () => {
      resolve(window[name]);
    });
    script.addEventListener('error', () => {
      reject(new Error(`Error loading ${url}`));
    });
    script.src = url;
    document.head.appendChild(script);
  });

  return window[name];
}
DaveTorrey commented 2 years ago

I also got that, I'm looking to see if there's some way I can edit it

Penggeor commented 1 year ago

@DaveTorrey Encounter the same issue.

fgagarin commented 3 months ago

In this implementation, it’s crucial to have the same module file name and a global property where the component will be loaded. Initially, the implementation places a promise in window[name], where name is the filename parsed from the URL.

...
window[name] = new Promise((resolve, reject) => {
...

However, once the module is loaded, it should replace the promise with the actual component, still using window[name], where name now represents the component name. E.g. how it's look like in my module:

(function (global, factory) {
  typeof exports === "object" && typeof module !== "undefined"
    ? (module.exports = factory(require("vue")))
    : typeof define === "function" && define.amd
      ? define(["vue"], factory)
      : ((global =
          typeof globalThis !== "undefined" ? globalThis : global || self),
        (global["endless-growth-experiment-description"] = factory(
          global.Vue,
        )));
})(this, function (vue) {
...

Look at the line global["endless-growth-experiment-description"] it has the same name as my file endless-growth-experiment-description.umd.cjs befor .umd part. So at the moment when resolve invoked there should be not a promise but component

...
resolve(window[name]);
...