一、微前端

微前端(Micro-Frontends)是一种类似于微服务的架构,它将微服务的理念应用于浏览器端,即将 Web 应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。微前端不是单纯的前端框架或者工具,而是一套架构体系。

目前的微前端框架一般都具有以下三个特点:

  • 技术栈无关:主框架不限制接入应用的技术栈,子应用具备完全自主权。
  • 独立性强:独立开发、独立部署,子应用仓库独立。
  • 状态隔离:运行时每个子应用之间状态隔离。

当然,微前端还存在许多的问题,比如应用间的 样式冲突、消息通信、脚本互斥、公共依赖加载等等。

二、应用隔离

应用隔离主要分两种情况:

  • 一种是 主应用与微应用之间的隔离;
  • 一种是 微应用与微应用之间的隔离;

应用间所隔离的主要是 Javascript 的沙箱隔离CSS 的样式隔离

CSS 样式隔离

由于在微前端场景下,不同技术栈的子应用会被集成到同一个运行池中,所以我们必须在框架层确保各个子主应用之间不会出现样式互相干扰的问题。

常见的解决方案

  • 严格的命名约定,例如 BEM;
  • CSS Module;
  • 各种 CSS-in-JS 库;
  • shadow DOM;

除了在css文件上做隔离,qiankun 也提供了样式隔离的功能。具体的方式有两种:严格样式隔离和 scoped 样式隔离。

qiankun 样式隔离方案

严格样式隔离

严格样式隔离,默认情况下是关闭的。如果需要开启,必须显示配置。

严格样式隔离,是基于 Web Component 的 shadow Dom 实现的。通过 shadow Dom, 我们可以将一个隐藏的、独立的 dom 附加到一个另一个 dom 元素上,保证元素的私有化,不用担心与文档的其他部分发生冲突。

scoped 样式隔离

scoped 样式隔离,是基于属性选择器实现的。类似 div["data-qiankun=react"]

html entry 解析以后的 html 模板字符串,在添加到 container 指定的节点之前,会先包裹一层 div,并且为这个 div 节点添加 data-qian 属性,属性值为子应用的 name 属性;然后遍历 html 模板字符串中所有的 style 节点,依次为内部样式表中的样式添加div["data-qiankun=xxx"]前缀。qiankun 中子应用的 name 属性值是唯一的,这样通过属性选择器的限制,就可实现样式隔离。

严格样式隔离和 scoped 样式隔离不能同时使用,当两者对应的配置项都为 true 时,严格样式隔离的优先级更高。

Javascript 沙箱隔离

通常,子应用在运行期间会有一些污染性的副作用产生,比如全局变量、全局事件、定时器、网络请求、localStorage、全局 Style 样式、全局 DOM 元素等。

为了保证应用能够稳定的运行且互不影响,需要提供安全的运行环境,能够有效地隔离、收集、清除应用在运行期间所产生的副作用,也就是沙箱的设计目标。

JS隔离的方式主要有两种,一种是快照拷贝的方式,一个是基于proxy的方式。

qiankun 优先使用 proxy沙盒,如果浏览器不支持 proxy ,那么再使用快照沙盒。

快照沙箱 - snapshotSandbox

在创建微应用的时候会实例化一个沙盒对象,它有两个方法,active是在激活微应用的时候执行,而inactive是在离开微应用的时候执行。

整体的思路是在激活微应用时将当前的window对象拷贝存起来,然后从modifyPropsMap中恢复这个微应用上次修改的属性到window中。在离开微应用时会与原有的window对象做对比,将有修改的属性保存起来,以便再次进入这个微应用时进行数据恢复,然后把有修改的属性值恢复到以前的状态。

代理沙箱 - proxySandbox

微应用中的script内容都会加with(global)来执行,这里global是全局对象,如果是proxy的隔离方式那么他就是下面新创建的proxy对象。

我们知道with可以改变里面代码的作用域,也就是我们的微应用全局对象会变成下面的这个proxy。

当设置属性的时候会设置到proxy对象里,在读取属性时先从proxy里找,没找到再从原始的window中找。

也就是你在微应用里修改全局对象的属性时不会在window中修改,而是在proxy对象中修改。因为不会破坏window对象,这样就会隔离各个应用之间的数据影响。

三、跨应用通信

微前端最常见的问题之一是如何让微应用之间能够相互通信。

一般而言,我们建议让微应用之间尽可能少地交流,因为这通常会重新引入我们最初试图避免的那种不适当的耦合代码。也就是说,通常我们只需要某种程度的跨应用通信即可。

常见的通信方式:

  • 使用 自定义事件通信,是降低耦合的一种好方法;
  • 可以考虑 React 或 Vue 应用中常见的 全局 state store 机制;
  • 发布-订阅(pub/sub)模式的通信机制;
  • 使用 地址栏作为通信机制;

qiankun - Actions 通信

qiankun 内部提供了 initGlobalState 方法用于注册 MicroAppStateActions 实例用于通信,该实例有三个方法,分别是:

  • setGlobalState:设置 globalState - 设置新的值时,内部将执行 浅检查,如果检查到 globalState 发生改变则触发通知,通知到所有的 观察者 函数。
  • onGlobalStateChange:注册 观察者 函数 - 响应 globalState 变化,在 globalState 发生改变时触发该 观察者 函数。
  • offGlobalStateChange:取消 观察者 函数 - 该实例不再响应 globalState 变化。

Actions 通信方案是通过全局状态池和观察者函数进行应用间通信,该通信方式适合大部分的场景。

四、微前端框架

Single-spa

Single-spa 是最早的微前端框架,兼容多种前端技术栈。

概念:Single-spa 是一个将多个单页面应用聚合为一个整体应用的 JavaScript 微前端框架。

我们都知道 spa 应用 的理念是让独立的应用程序组成一个完整的页面,Single-spa 并不用依赖于单个框架和每个特性,而是你可以在不同的新框架随意使用。

简单来说就是一个聚合,使用这个库可以让你的应用可以 使用多个不同的技术栈(vue、react、angular等等)进行同步开发,最后使用一个公用的路由去实现完美的切换。

优点:

  • 敏捷性 - 独立开发、独立部署,微应用仓库独立,前后端可独立开发,部署完成后主框架自动完成同步更新;
  • 技术栈无关,主框架不限制接入应用的技术栈,微应用具备完全自主权;
  • 增量升级,在面对各种复杂场景时,我们通常很难对一个已经存在的系统做全量的技术栈升级或重构,而微前端是一种非常好的实施渐进式重构的手段和策略
  • 更快交付客户价值,有助于持续集成、持续部署以及持续交付;
  • 维护和 bugfix 非常简单,每个团队都熟悉所维护特定的区域;

缺点:

  • 无通信机制
  • 不支持 Javascript 沙箱
  • 样式冲突
  • 无法预加载

Qiankun

Qiankun 是一个基于 single-spa ,阿里系开源的微前端框架,旨在帮助大家能更简单、无痛的构建一个生产可用微前端架构系统。

优点:

  • 基于 single-spa 封装,提供了更加开箱即用的 API。
  • 技术栈无关,任意技术栈的应用均可 使用/接入,不论是 React/Vue/Angular/JQuery 还是其他等框架。
  • HTML Entry 接入方式,让你接入微应用像使用 iframe 一样简单。
  • 样式隔离,确保微应用之间样式互相不干扰。
  • JS 沙箱,确保微应用之间 全局变量/事件 不冲突。
  • 资源预加载,在浏览器空闲时间预加载未打开的微应用资源,加速微应用打开速度。
  • umi 插件,提供了 @umijs/plugin-qiankun 供 umi 应用一键切换成微前端架构系统。
  • 社区较为活跃,维护者也较多,有问题会及时得到响应;

缺点:

  • 可能对一些 jQuery 老项目支持性不是特别好;
  • 安全和性能可能会有影响,具体取决于项目;
  • 对 eval 的争议,eval函数的安全和性能是有一些争议的

Web Component

基于 Web Component 原生组件进行渲染的微前端框架有京东推出的 Micro App。

优点:

  • 简单上手
  • 无关技术栈:任何框架皆可使用;
  • 静态资源补全;
  • JS沙箱;
  • 样式隔离;
  • Qiankun 微前端框架的优势他都有;

另外腾讯推出的无界,也是一款基于 Web Components + iframe 微前端框架,具备成本低、速度快、原生隔离、功能强等一系列优点。

五、微前端使用过程中出现的问题

1. 微应用之间、主微应用之间相互跳转

用子应用router的history跳转会带上子应用的base,导致路由跳转404。这就造成使用微应用 router 的方法无法跳回主应用,也就无法直接跳到其他微应用。

解决方法

  1. 通过window.history.pushState()方式跳转。
  2. 将主应用的路由实例通过 props 传递给子应用,子应用使用主应用的路由实例进行跳转。
  3. 通过浏览器的自定义事件(document.dispatchEvent)传递主应用的history。

2. antd组件库的全局样式污染

如果是子应用之间的antd版本不用,那么不会有影响,但是主应用和子应用之间的版本问题会出现样式冲突

解决方法

  1. 使用@ant-prefix 这个变量给 antd 添加 namespace 的效果
  2. 使用qiankun提供的 scoped 隔离样式功能,如果使用这个功能,需要对Modal做一些处理

参考链接:
微前端学习系列(三):qiankun
除了 Qiankun, 这些微前端框架或许更适合你「建议收藏」
30分钟快速掌握微前端qiankun的所有核心技术
深入解析微前端乾坤原理
qiankun微应用之间、主微应用之间相互跳转方式总结与实践
你可能不需要微前端
微前端在美团外卖的实践

前端 - 用微前端前应该了解的一些知识点相关推荐

  1. qiankun 微前端_微前端方案 qiankun(实践及总结)

    ❝ 作者:沉末_ 链接:https://juejin.im/post/5ed73b73e51d4578724e3fa4 ❞ 什么是微前端? 我们先来看两个实际的场景: 1. 复用别的的项目页面 通常, ...

  2. 前端怎么使用jsessionid_前端搞微前端 | 侑夕 - 如何落地微前端一体化运营工作台...

    下期预告 前端早早聊大会目标成为用得上.听得懂.抄得走的技术大会,计划 2020 年办 >= 15 期,由前端早早聊与掘金联合举办,前端早早聊大会行程动态.录播视频/PPT/讲稿资料下载请关注 ...

  3. 闲庭信步聊前端 - 见微知著微前端

    笔者初次接触微前端在2020年7月,是从同事的口中听说的.虽然不算是一个早期接触者,但是也确实的推动和跟进了内部某大型项目的开发和落地.也希望能把一些走过的坑和一些思考分享给大家.文内所指应用均为PC ...

  4. 乾坤 微前端_微前端架构初探以及我的前端技术盘点

    前言 最近几年微前端一直是前端界的热门议题, 它类似于微服务架构, 主要面向于浏览器端,能将一个复杂而庞大的单体应用拆分为多个功能模块清晰且独立的子应用,且共同服于务同一个主应用.各个子应用可以独立运 ...

  5. postmessage 游戏窗口内无效_前端的微前端在交通项目内的应用实践

    项目背景 业务的快速发展,越来越多的接入渠道(百度.快应用等等),人员增加,开发成本与管理成本都上升,效率反而越来越低,团队的人员重复造轮子,毫无挑战,当然市面上也有多端解决方案,但是不太适用目前的业 ...

  6. qiankun 微前端_qiankun 微前端应用实践与部署(二)

    下面是两种方案的简要描述. 传统部署 方式 通过配置 nginx 端口到目录的转发. 具体可查看上一篇文章 特点 需要对外开放子应用对应的端口,将编译好的应用文件放到对应的配置目录. docker 部 ...

  7. bootstrap跟vue冲突吗_知道微服务,但你知道微前端吗?

    在 toB 的前端开发工作中,我们往往就会遇到如下困境: 工程越来越大,打包越来越慢 团队人员多,产品功能复杂,代码冲突频繁.影响面大 内心想做 SaaS 产品,但客户总是要做定制化 不同的团队可能有 ...

  8. 三、如何手动实现一个微前端框架雏形

    如何手动实现一个微前端框架雏形 一.了解微前端 1. 什么是微前端 为了解决一整块儿庞大的前端服务所带来的变更和拓展方面的限制,将整体前端服务拆分成一些更小.更简单的,能够独立开发.测试部署的小块儿. ...

  9. py获取前端的参数_微前端 qiankun 项目实践

    (给前端大全加星标,提升前端技能) 作者:zxh1307 https://juejin.im/post/5ea55417e51d4546e347fda9 导语 最近在做微前端的项目 , 过程中真是踩了 ...

最新文章

  1. linux下热插拔事件的产生是怎样通知到用户空间,kobject_uevent_env之uevent【转】...
  2. 【译】一份通俗易懂的React.js基础指南-2018
  3. 细说Redis监控和告警
  4. Mocha and Math 运算
  5. python 等值线 标注 间距、控制_python - Matplotlib-Contourf-如何使刻度线间距不均匀? - 堆栈内存溢出...
  6. 为什么你总成为不了架构师?
  7. 第42讲:scrapy框架的基本使用
  8. mutt的实现, mutt+msmtp+getmail配置
  9. Java--对象内存布局
  10. c#中用声音提示报警(转)
  11. python 正则表达式匹配的位置_python正则表达式匹配 模式匹配
  12. 使用Facelets开发JSF程序
  13. Android学习视频精品课程汇总(持续更新)
  14. 谷歌浏览器如何下载在线音频视频
  15. 鲁大师2022半年报显卡排行,NVIDIA霸榜,七彩虹成最大赢家!
  16. 2016年英语六级翻译
  17. linux里面的注释命令是啥,LINUX基础命令注释大全
  18. 学习笔记(03):ArcGIS10.X入门实战视频教程(GIS思维)-坐标系与地理坐标系
  19. python 筛选重复数据和不重复数据_[Python] Pandas 对数据进行查找、替换、筛选、排序、重复值和缺失值处理...
  20. android倒计时停止,Android 使用 Timer 做倒计时。实现开始 (start),取消 (cancel),暂停 (pause),重开 (resume)功能...

热门文章

  1. 带头结点的单链表就地逆置
  2. 随机行走(random walk)
  3. PetiteVue - Vue 作者尤雨溪新作品,小巧精简版的 Vue
  4. 经典算法案例001-08:如何使用质数设计扫雷(Minesweeper)游戏
  5. 配送计算价格(含距离+时间段+基础费用+重量等因素)
  6. 计算机网络——奈式准则和香农定理
  7. python小程序 大小五角星
  8. angular项目中配置文件实践
  9. Linux中后台启动redis-server
  10. java获取mysql表的主键_Spring中获取数据库表主键序列