浅时光吖~  
生活明朗,万物可爱,加油~

1.背景:

随着业务的越来越大,打包工具的打包速度已经不能满足日常开发;技术栈的升级又不想对老代码进行重构,但新的代码业务想开始尝试新的技术栈;多个业务之间相同模块的复用等一系列问题;这就开始寻求一种新的解决方案,将应用拆解成多个更小、更易管理的小应用,一种由多个独立可交付的前端应用组合而成更庞大整体的架构方式成为微前端。
微前端架构是一种类似于微服务的架构,由ThoughtWorks 2016年提出,它将微服务的理念应用于浏览器端,即将 Web 应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。

2.微前端架构模型:

该方案的核心是主从思想,即包括一个基座(MainApp)应用和若干个微(MicroApp)应用,基座应用大多数 是一个前端SPA项目,主要负责应用注册,路由映射,消息下发等,而微应用是独立前端项目,这些项目不限于采 用React,Vue,Angular或者JQuery开发,每个微应用注册到基座应用中,由基座进行统一管理.

 

 

 

3.微前端架构具备以下几个核心价值

  • 和技术栈无关,主框架不限制接入应用的技术栈,子应用具备完全自主权。
  • 独立开发、独立部署。子应用仓库独立,前后端可独立开发,部署完成后主框架自动完成同步更新。
  • 独立运行时,每个子应用之间状态隔离,运行时状态不共享。
  • 新功能使用新框架,旧的单页应用不用重写可以共存。
  • 每个独立模块的代码可做到按需加载,不浪费额外资源。

 

4.single-spa微前端和iframe

1.iframe:

缺点:

  • 页面加载问题: 影响主页面加载阻塞onload事件,本身加载也很慢,页面缓存过多会导致电脑卡顿。
  • 布局问题:iframe必须给一个指定的高度,否则会塌陷。解决办法:子系统实时计算高度并通过postMessage发送给主页面,主页面动态设置高度,修改子系统或者代理插入脚本。有些情况会出现多个滚动条,用户体验不佳。
  • 弹窗及遮罩层问题:只能在iframe范围内垂直水平居中,没法在整个页面垂直水平居中。
  • iframe里面的内容无法实现占满屏幕的弹窗(非全屏),他只能在iframe范围内全屏,无法跳出iframe的限制在主页面全屏,不过这种情况也很少。
  • 浏览器前进/后退问题:iframe和主页面共用一个浏览历史,iframe会影响页面的前进后退,大部分时候正常,iframe多次重定向则会导致浏览器的前进后退功能无法正常使用,不是全部页面都会出现,基本可以忽略。但是iframe页面刷新会重置(比如说从列表页跳转到详情页,然后刷新,会返回到列表页),因为浏览器的地址栏没有变化。
  • iframe的页面跳转到其他页面出问题,比如两个iframe之间相互跳转,直接跳转会只在iframe范围内跳转,所以必须通过主页面来进行跳转。
  • 不同源的系统之间的通讯需要通过postMessage,存在一定的安全性。

优点:

  • 完全隔离了css和js,避免了各个系统之间的样式和js污染
  • 可以在子系统完全不修改的情况下嵌入进来
  • 改动小,使用简单

2.single-spa

优点

  • 加载快,可以将所有系统共用的模块提取出来,实现按需加载,一次加载,其他的复用。
  • 修改子系统的样式,不需要代理服务器,直接修改,因为同属于一个document。
  • 用户体验好、快,内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染
  • http请求少,服务器压力小。

缺点

  • css和js需要制定规范进行隔离。否则容易造成全局污染,尤其是vue全局组件,全局钩子等
  • 需要子系统配合修改,统一规范。

5.single-spa搭建

官方文档:https://single-spa.js.org/docs/create-single-spa/

 

 

1.yarn global add create-single-spa@2.0.3 (全局安装single-spa)

  • single-spa root config创建基座容器
  • single-spa application / parcel创建子项目,react,angular,vue和其他类型应用
  • in-browser utility module (styleguide, api cache, etc)创建公共模块应用,非渲染组件,用于跨应用共享JavaScript逻辑的微应用

 

2.yarn create single-spa创建基座容器。你也可以不选用脚手架搭建,用vue,react这些框架引入single-spa来搭建

  • 选择single-spa root config创建基座容器
  • 填入文件名,组织名称,应用名称。组织名称可以理解为团队名称,微前端架构允许多团队共同开发应用,组织名称可以标识应用
     由哪个团队开发。应用名称的命名规则为 @组织名称/应用名称 ,比如 @study/todos
  • 按需要是否引入ts,single-spa layout Engine等功能
  • 安装好以后找到package.json的start脚本运行基座容器,默认9000端口

 

 

 

 

 

基座目录结构:

 

 

registerApplication:注册项目,接受四个参数

  • name:项目名称
  • app:项目路径
  • activeWhen:项目路由,回调函数入参 location 对象,可以写自定义匹配路由加载规则。例如:activeWhen: location => location.pathname === '/welcome', //完全匹配
  • customProps:项目入参,接受一个对象

singleSpa.start:这是启动函数。

 

3.yarn create single-spa(创建react,angular,vue和其他类型应用)

  • 选择single-spa application / parcel创建子项目
  • 填入文件名和团队名称
  • 按需要是否引入框架里的扩展功能
  • 安装好以后找到package.json的start脚本运行子项目

 

 

vue项目:(选择Vue2和Vue3都可以,我这里演示是Vue3,运行成功入下图)

 

 

  • 设置路由,设置const routerHistory = createWebHistory("vue-app"),vue-app为区分项目的根路由
  • install安装路由依赖,设置端口号为9001

 

 

 

 

react项目:(运行成功入下图)

 

 

  • 设置路由,react-app为区分项目的根路由
  • install安装路由依赖,设置端口号为9002
  • 配置webpack,忽略打包react依赖

 

 

 

 

4.single-spa基座配置

  • 引入项目公共包和入口

 

 

  • 路由导航和项目挂载

 

 

  • 注册应用

 

 

5.single-spa路由分发

本地运行默认端口是9000,通过一级路由来区分应用1,应用2,二级路由为应用的业务路由

 

 

6.single-spa项目之间消息通知和数据共享

 

 

通信: 项目A和项目B之间完全隔离没有任何交集,通信方式是通过基座的订阅和下发来实现。基座容器接受A项目或者其本身消息/状态改变,通过customProps入参传给B项目达到通信目的。

解决思路:可以使用发布订阅模式实现,实现一个类似于Vuex,Redux 的状态管理。基座封装信息接收和传达的方法,统一管理通信。

 

 


7.single-spa项目样式隔离和组件拆分

1、样式隔离:我们使用postcss的一个插件:postcss-selector-namespace。
                       他会把你项目里的所有css都会添加一个类名前缀。这样就可以实现命名空间隔离。
                       首先,我们先安装这个插件:npm install postcss-selector-namespace --save -d
                       项目目录下新建 postcss.config.js,使用插件:

 

 

2、组件拆分:业务组件可以存在各个项目自己的组件库中,公共组件可以抽离发布成npm包

 

8.single-spa 统一授权

  1. 场景1:A项目独立部署,B项目独立部署,A和B各自有自己的登录页,账号密码。(用户)
  2. 场景2:开发时开发者需要整个系统的访问权。(开发者/管理者)

      解决思路:对接统一授权接口,后端进行连表拉取A和B的用户来鉴权,返回token,路由信息并区分登录途径。前端接收后端的路由信息,通过路由守卫来渲染模块。

 

9.single-spa模块化加载

基本思想:开发过程中,我只想开发A/AB项目,那我就只启动打包A/AB项目(甚至我还可以选择A项目里面的一个或者几个模块)。未启动的项目路由访问404。按需加载,打包速度很快。

步骤:npm run start → 请选择项目 → 请选择模块 → 请选择开发环境 → 启动成功

 

10.single-spa 自动化打包和部署

基本思想:目前通过Jenkins工具打包需要时间较长,而且可能出现排队的情况,部署较慢,服务器主机处于高负荷状态。通过开发者的机器本地打包后自动化上传部署,可以节省时间和资源,大大提高效率。

步骤: npm run build → 请选择需要打包的项目(可多选) →  打包成功后需要部署吗(Y) → 请选择要部署的环境 → 多线程打包中... →  打包成功正在上传服务器部署 →  xxx环境部署成功

 

6.single-spa搭建过程中可能遇到的坑

1.基座

  • 未引入公共包运行报错。
  • 引入项目路径(建议打包以后查看),而且要统一配置端口号

 

 

2.Vue项目

  • vue3路由,router-link标签失效。解决方法:npm install vue-router@next --save

 

 

3.react项目

  •  webpack.config.js过滤打包react-dom

 

 

 

4.vue 和 react/angular 挂载的区别:

Vue 2.x的dom挂载,采取的是 覆盖Dom挂载 的方式。例如,组件要挂载到#app上,那么它会用组件覆盖掉#app元素。

但是React/Angular不同,它们的挂载方式是在目标挂载元素的内部添加元素,而不是直接覆盖掉。
例如组件要挂载到#app上,那么他会在#app内部挂载组件,#app还存在。

这样就造成了一个问题,当我从 vue子项目 => react项目 => vue子项目时,就会找不到要挂载的dom元素,从而抛出错误。

解决这个问题的方案是,让 vue项目组件的根元素类名/ID名和要挂载的元素一致 就可以。

例如我们要挂载到 #app 这个dom上,那么我们子项目内部的app.vue,最顶部的dom元素id名也应该叫 #app

 

 

 

 

 

 

 

posted on 2021-12-03 11:41  浅时光吖~  阅读(649)  评论(0编辑  收藏  举报