微前端项目实战及原理

背景

使用微前端在项目中主要是解决使用iframe引入第三方页面时遇到的框架受限,页面交互不统一等问题,项目中遇到的问题大概如下:

  1. iframe 内部路由跳转,不会影响到外部的路由地址,无法记住当前访问的页面地址,iframe加载第三方公司应用,在 iframe 里面发生的页面跳转,外部的路由地址是不会变化的,如果我刷新页面,它又回到的之前的页面。
  2. iframe 内部的弹窗遮罩问题,iframe内部的弹窗只在内部生效,这样看上去就和左侧菜单以及头部分离了,页面看起来不美观,与正常的UI交互不一致
  3. iframe 的高度不是自适应的,必须由 js 来动态 调整
  4. 存在重复加载资源问题

除此之外,微前端的初衷是解决遗留老项目更新维护困难的问题,那么到底什么是微前端呢?

什么是微前端

在这里插入图片描述
如果我们把页面看成是最终向用户展示产品的窗口,那么窗口里面的每一项,每一个小块,每一个功能,都可以由不同的技术,不同的框架来完成。

在这个图中,我们的窗口包含头部、左侧、内容和脚部 这四部分,中间是内容区,内容区的部分可以加载任何符合规范的前端代码,不论你是用 react、vue还是 angular 来开发的,只要你符合规范的约定,我就可以把你的内容加载过来。

它把前端开发从原来的基于一个大框架下的开发,拆分成了基于功能的若干微小的开发,各个端之间业务独立,互不影响,一个端出问题了也不会影响到其它端,所以把它称之为微前端。

微前端的特点:
1、与技术栈无关
2、子应用独立部署
3、子应用与主应用无缝衔接,主应用对子应用可控,子应用可获取主应用资源(看上去就是一个应用一样)

其中第三点就是区别于 iframe 的地方,因为 iframe 无法做到这一点

实现原理

介绍完什么是微前端后,那接下来介绍下微前端的实现原理
在这里插入图片描述微前端实现原理是 主工程在运行时获取应用配置,然后注册应用和路由,先加载主应用(菜单等),当url 地址变化时,通过路由管理器和应用管理器动态加载对应的子应用

路由管理器是指把所有子应用的路由统一放在一个总路由里管理,应用管理器是把所有子应用打包后的实例放在一个应用管理器里,当URL和路由管理器中的子应用路由匹配时,通过应用管理器加载对应的子应用

基于这个原理,我画了一个流程图:
在这里插入图片描述
子应用在加载前会创建基于自身的生命周期实例和路由,然后注册到主工程中,当页面URL跳转时,通过路由管理器和应用管理器匹配子应用,在加载子应用的过程中,有三个生命周期,bootstrap是初始化,这个时候页面显示loading,也就是正在加载中,然后走到mount,开始加载页面,不需要显示当前子应用时,通过unmount卸载子应用

核心的技术是 systemjs 和Single-Spa
在这里插入图片描述

systemjs 提供通用的模块导入途径,支持传统模块和ES6的模块,相当于加载器,主要用来调度子应用,决定何时展示哪个子应用。
single-spa 包装器,可以把现有的应用包装,使得加载器可以使用它们
说下这两个技术点的原理,最核心的原理其实很简单,抛出 各个规范不讲, 只讲最核心的 JS 函数。

在这里插入图片描述主要做的是:

  1. 根据远程地址,可以加载 JS、CSS 等文件。
  2. 根据 AMD 的模块规范,动态创建script标签,把远程加载的文件,按照 ES Module 规范载入并执行。
    在这里插入图片描述single-spa 原理:

1.根据主应用的注册信息,找到所有的子应用。
在这里插入图片描述
3. 然后根据路由匹配的情况,发起一个路由匹配应用事件(single-spa:routing-event),在结合 SystemJS.import 方法去加载文件

技术细节

在这里插入图片描述我将按照项目架构、路由分发、应用加载和公用依赖加载这四个流程来为大家介绍
在这里插入图片描述
首先看下项目架构,这是主框架,由 index.html 和公用部分navbar 及子应用 app1 组成,其他子应用和 app1的实现原理一样
在这里插入图片描述
index.html 相当于总入口,配置所有资源
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
然后说下路由分发,也就是主框架是怎样通过路由找到每个子应用的

以demo中的菜单为例,菜单navbar 和首页index 以及弹窗遮罩APP1 都是单独的子应用,这些子应用的路由都放在主框架的路由管理器里,运行页面就加载菜单栏,所以主框架初始化就运行navbar路由,默认导航到首页,点击弹窗遮罩菜单项,url变成 /app1,通过路由分发 ,路由管理器找到 app1 对应的子应用名称,再去应用管理器里找到这个子应用,加载到主框架

在这里插入图片描述
通过路由分发,子应用是怎样挂载到主框架

先说子应用,子应用创建 vue 的实例和项目加载前,加载后,卸载时的钩子函数,并暴露到全局,通过setPublicPath这个方法生成对应的路由,这个路由是唯一的,并暴露到全局,这样子应用的路由和实例都暴露到全局中,在主框架中就容易拿到子应用的配置
在这里插入图片描述
主框架通过 SystemJS 把子应用的入口 js 文件加载进来,通过singleSpa.registerApplication注册路由和应用,

当url前缀和应用的路由匹配时,就会加载应用
在这里插入图片描述
最后说下公共依赖是怎么加载的
公共依赖是指子应用和主框架可以共用的依赖,像 vue、vue-router、webpack等
这些公共依赖放在主框架中,子应用在vue.config.js文件通过config.externals 配置共用依赖,这样需要时,就从主框架加载
在这里插入图片描述

主框架通过 systemjs-importmap 把需要的公用依赖文件导入进来,通过 System.import 使用依赖

结语

目前项目已经改造完成,踩了不少坑,微前端已封装成插件放到前端生态中,整体是参考阿里 qiankun 框架,后续也会不断总结并发布到博客中。

  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值