【问题标题】:Vue3 / vite External ComponentVue3 / vite 外部组件
【发布时间】:2020-12-30 13:22:18
【问题描述】:

似乎我在 vue 中加载外部 umd 组件时遇到了问题。

我尝试做类似的事情

Vue 3 external component/plugin loading in runtime

这适用于我使用 vue2 和 webpack

现在我使用的是 Vue3/Vite,并且与上述问题中的来源相同。

但是在解决外部组件承诺时,我收到以下错误:

vue.js:1184 [Vue warn]: Unhandled error during execution of async component loader 
  at <AsyncComponentWrapper> 
  at <DemoComponent> 
  at <HelloWorld msg="Hello Vue 3.0 + Vite" > 
  at <App>
warn @ vue.js:1184
logError @ vue.js:1357
handleError @ vue.js:1349
onError @ vue.js:4637
(anonymous) @ vue.js:4677
Promise.catch (async)
setup @ vue.js:4676
callWithErrorHandling @ vue.js:1300
setupStatefulComponent @ vue.js:7561
setupComponent @ vue.js:7522
mountComponent @ vue.js:5264
processComponent @ vue.js:5240
patch @ vue.js:4861
mountChildren @ vue.js:5043
processFragment @ vue.js:5203
patch @ vue.js:4854
componentEffect @ vue.js:5357
reactiveEffect @ vue.js:339
effect @ vue.js:314
setupRenderEffect @ vue.js:5322
mountComponent @ vue.js:5280
processComponent @ vue.js:5240
patch @ vue.js:4861
mountChildren @ vue.js:5043
processFragment @ vue.js:5203
patch @ vue.js:4854
componentEffect @ vue.js:5357
reactiveEffect @ vue.js:339
effect @ vue.js:314
setupRenderEffect @ vue.js:5322
mountComponent @ vue.js:5280
processComponent @ vue.js:5240
patch @ vue.js:4861
mountChildren @ vue.js:5043
processFragment @ vue.js:5203
patch @ vue.js:4854
componentEffect @ vue.js:5357
reactiveEffect @ vue.js:339
effect @ vue.js:314
setupRenderEffect @ vue.js:5322
mountComponent @ vue.js:5280
processComponent @ vue.js:5240
patch @ vue.js:4861
render @ vue.js:5937
mount @ vue.js:4168
app.mount @ vue.js:9324
(anonymous) @ main.js:7
Show 16 more frames
external-component.js:11 Uncaught (in promise) TypeError: Chaining cycle detected for promise #<Promise>
    at <anonymous>
    at HTMLScriptElement.<anonymous> (external-component.js:11)

这是承诺的代码

export default async function externalComponent(url) {
const name = url.split(`/`).reverse()[0].match(/^(.*?)\.umd/)[1];
if (window[name]) return window[name];
console.log('run');
window[name] = new Promise((resolve, reject) => {
script.async = true;
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];
}

并在我的 DemoComponent 中使用它:

<script lang="ts">
import externalComponent from '../external-component';
import { defineAsyncComponent } from 'vue'
const asyncComponent = defineAsyncComponent(
() => externalComponent(`http://localhost:8200/MyComponent/MyComponent.umd.min.js`)
)
export default {
name: 'DemoComponent',
components:  {
     MyComponent:asyncComponent
},
....

有人可以帮我吗?

【问题讨论】:

    标签: vue.js


    【解决方案1】:

    更新:

    如果从 vue/dist/vue.esm-bundler 导入 vue 并设置为全局,则无需更改 Vite 配置,也无需从 cdn 加载 vue。

    import * as Vue from 'vue/dist/vue.esm-bundler';
    window.Vue = Vue;
    

    尝试上面的链接后,我收到了vue warn invalid vnode type symbol(static) (symbol) 错误。

    通过在 Vite.config.js 中添加以下配置,它对我有用。

    // vite.config.js
    import { viteExternalsPlugin } from 'vite-plugin-externals'
    
    export default {
      plugins: [
        viteExternalsPlugin({
          vue: 'Vue'
        }),
      ]
    }
    

    https://github.com/crcong/vite-plugin-externals

    【讨论】: