Vue 3 外部组件/插件在运行时加载 [英] Vue 3 external component/plugin loading in runtime

查看:33
本文介绍了Vue 3 外部组件/插件在运行时加载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为具有基于分布式模块的所有权的 Vue 3 应用程序设计架构.模块系统将用插件表示(似乎是最合适的解决方案,允许 vuex 模块和 vue-router 动态注入).每个这样的模块/插件将由在独立存储库中工作的专门团队开发.我们不能使用 npm package-per-plugin 方法,因为部署过程也应该被隔离,并且使用 npm 方法核心应用程序团队必须每次 重建应用程序npm 包插件有更新.这意味着我们必须在运行时通过 http 加载此类插件/页面.

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.

到目前为止这种方法作者:Markus Oberlehner 似乎是某种方式 - 它使用基于自定义 Promise 的解决方案来解决 webpack 缺少的在运行时加载外部 url 脚本"的问题.功能.虽然它在 Vue 2 上运行良好,但 Vue 3 会出现 VNode type: undefined 错误.

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.

上述文章提供了以下webpack外部组件加载方案:

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];
}

但是上面,正如我所说,不适用于 Vue 3 defineAsyncComponent 机制.

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')
)

所以我有两个问题:

  1. 对于上述架构规范,是否有任何已知的更好的解决方案/建议?

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

是否有任何使用 Vue 3 测试过的有效 webpack 动态外部导入解决方案?

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

UPD:这里是小的复制仓库

推荐答案

我们通过聊天一起解决了这个问题.

We solved this problem together via chat.

通过 Vue 3 vue-cli 构建的组件依赖于 Vue 在全局范围内可用.因此,为了渲染通过我文章中描述的技术加载的组件,您需要将 window.Vue 设置为对 Vue 本身的引用.然后一切都按预期进行.

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.

这篇关于Vue 3 外部组件/插件在运行时加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆