Vue 3 external component/plugin loading in runtime

两盒软妹~` 提交于 2021-02-17 05:27:05

问题


I am designing an architecture for the Vue 3 app with distributed module-based ownership. Module system will be represented with plugins (seems like the most appropriate solution allowing vuex module and vue-router dynamic injects). Each such module/plugin will be developed by dedicated team working within isolated repos. We cannot use npm package-per-plugin approach as deployment process should be isolated as well, and with npm approach core app team will have to rebuild app each time npm package plugin has updates. This means we will have to load such plugins/pages at runtime via http.

So far this approach by Markus Oberlehner seems like some sort of the way to go - it uses custom Promise based solution for webpack's missing "load external url script at runtime" functionality. While it works fine with Vue 2, Vue 3 gives VNode type: undefined error.

The above mentioned article offers the following webpack external component loading solution:

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

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

    window[name] = new Promise((resolve, reject) => {
        const script = document.createElement('script');
        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];
}

But above, as I said, does not work with Vue 3 defineAsyncComponent mechanism.

// 2.x version WORKS
const oldAsyncComponent = () => externalComponent('http://some-external-script-url.js')

// 3.x version DOES NOT WORK
const asyncComponent = defineAsyncComponent(
    () => externalComponent('http://some-external-script-url.js')
)

So I have two questions:

  1. Are there any known better solutions/suggestions for above architectural specification?

  2. Is there any working webpack dynamic external import solutions tested with Vue 3 out there?

UPD: Here is small reproduction repo


回答1:


We solved this problem together via chat.

Components built via the Vue 3 vue-cli rely on Vue being available in the global scope. So in order to render components loaded via the technique described in my article, you need to set window.Vue to a reference to Vue itself. Then everything works as expected.



来源:https://stackoverflow.com/questions/63581504/vue-3-external-component-plugin-loading-in-runtime

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!