You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3/Vite加载外部UMD组件出现Promise循环链错误求助

Fix: Chaining Cycle Detected for Promise When Loading External UMD Components in Vue3 + Vite

Let me break down what's causing your error and how to fix it step by step.

Root Cause

The TypeError: Chaining cycle detected for promise happens because your code creates a Promise that ultimately resolves to itself. Here's why:

  1. You assign window[name] to a new Promise
  2. In the script's load handler, you try to resolve that same window[name] (which is still the Promise itself if your UMD component didn't properly overwrite it)
  3. This creates a circular reference in the Promise chain, triggering the error

Also, I noticed your code is missing the line to create the script element (const script = document.createElement('script')) — that would cause an additional error, so I'll fix that too.

Corrected Code

Here's the revised externalComponent function that fixes the cycle and adds better error handling:

export default async function externalComponent(url) {
  // Extract component name from the UMD filename
  const name = url.split(`/`).reverse()[0].match(/^(.*?)\.umd/)[1];

  // Return immediately if the component is already loaded (not a cached Promise)
  if (window[name] && typeof window[name] !== 'object') {
    return window[name];
  }

  // Create a new script element (this was missing in your original code!)
  const script = document.createElement('script');
  script.async = true;

  // Create a Promise to wait for the script to load and execute
  const loadPromise = new Promise((resolve, reject) => {
    script.addEventListener('load', () => {
      // Verify the component was actually mounted to window by the UMD script
      if (window[name]) {
        resolve(window[name]);
      } else {
        reject(new Error(`Component "${name}" not found on window after loading script`));
      }
    });

    script.addEventListener('error', () => {
      reject(new Error(`Failed to load external script: ${url}`));
    });
  });

  // Cache the Promise to avoid duplicate script requests
  window[name] = loadPromise;

  // Trigger the script load
  script.src = url;
  document.head.appendChild(script);

  // Return the Promise that resolves to the actual component
  return loadPromise;
}

Key Fixes & Improvements

  1. Avoids Promise Cycles: We resolve the actual component (mounted to window[name] by the UMD script) instead of resolving the cached Promise itself.
  2. Explicit Script Creation: Adds the missing script element initialization.
  3. Better Cache Checks: Ensures we only return the cached value if it's the actual component (not the pending Promise).
  4. Clearer Error Messages: Helps debug cases where the UMD script fails to load or doesn't expose the component correctly.

Additional Troubleshooting Tips

  • Verify UMD Component Name: Make sure the libraryName configured in your UMD component's build tool (e.g., Vite/Webpack) exactly matches the name extracted from the URL (including capitalization). If they don't match, window[name] will never be overwritten with the component.
  • Check Browser Console: After loading the script, run window[name] directly in the browser console to confirm the component is mounted correctly.
  • Vue3 Compatibility: Ensure your UMD component is built for Vue3 — Vue2 components won't work correctly in Vue3 runtime.

内容的提问来源于stack exchange,提问作者Peter Siegel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:24:57