【动态加载远程CDN组件的核心原理】
一、用vite将组件打包为umd模块,放到CDN 二、管理端有一个页面,专门维护 组件的基本信息,包括版本信息、远程地址等
三、管理端加载远程组件:
1、从左侧拖入组件的时候,带着组件的基本信息(组件类型,名称,远程CDN地址等) 2、管理端加载远程组件是使用vue3的 defineAsyncComponent 方法
defineAsyncComponent 里面接收一个loader ,需要返回一个Promise , 这个Promise 就是加载远程组件的Promise
const promise = new Promise((resolve,reject)=>{
}) const component = defineAsyncComponent({ loader:promise })
3、Promise 具体怎么实现呢?就是当加载完远程组件的时候,resolve组件 4、如何加载远程组件?答案是动态创建 script 标签 去加载 ,script标签的地址就是 组件的cdn远程地址 动态创建的 script 标签,还要带上其他字段,标识这个远程组件的一些其他信息,比如
5、什么时候加载完成,就是 resolve 的时机!!那就是 远程组件里面的 js 执行的时候,就是加载完成的时候
所以,要将创建的promise 里面的resolve缓存到全局 const map = {
} const promise = new Promise((resolve,reject)=>{ const key = 'xxxxxxx' // 由组件的type 和 版本等信息组成 map[key]=resolve })
6、在 每个远程组件里面,都要调用resolve import component from './src'
map[key].resolve(component) key 怎么获得呢?怎么知道是哪个组件?是通过 const key = document.currentScript?.dataset['component']
这样 获取script 标签上的属性 data-component 得到的
7、管理端在发布的时候,动态拼接,生成一个html,放到CDN
这里主要包含了 核心渲染库,公共依赖,以及 所有的 当前页面的 远程组件至此,管理端逻辑结束
【C端页面渲染逻辑】 一、C端页面 全局创建一个
map ={}
每个远程组件里面,都将组件的默认导出,放到map里面 类似于管理端上面第6点,管理端是将组件 resolve,C端不需要,C端只需要放到全局 map 里面;
然后,遍历这个map ,C端全局注册所有这些组件 app.component(iterator[0], iterator[1].component);
所有远程组件都注册了,那就直接 使用 pageConfig 中 schema数据,遍历渲染组件就OK Vue.h(component, { config: com.config });