前端开发微前端的含义和发展趋势以及发展方向分析-乐题库
前端开发微前端的含义和发展趋势以及发展方向分析-乐题库我们很自然地会将整个系统拆解到多个子应用/子项目中,他们可以独立开发、独立部署,但共同协作支撑了系统的整体功能。不同的前端团队,可以独立开发和部署他们的应用,满足自己的迭代需求个朴素的HTML页面/应用,可能很难通过传统前端框架实现,甚至,大多数区域级微前端(section-level)也无法完成。让我们来看下如何搭建零界微前端。我们在接入零界的微应用上,也只做了两个改动:
一、 前言
1.1 微前端的含义
在研发一个系统的初期,我们可以把所有代码放到一个项目中。随着企业的发展,业务逻辑越发复杂和专业化,又会细分出不同的研发团队,独立负责其中某一部分。
每个开发团队有他们各自的迭代节奏,很难在耦合的同一个项目中,满足所有团队的需求。我们很自然地会将整个系统拆解到多个子应用/子项目中,他们可以独立开发、独立部署,但共同协作支撑了系统的整体功能。
当上述系统拆解过程,发生在后端时,它被称之为——微服务;当它发生在前端时,则被称之为——微前端。
从某种意义上,微前端是默认值,不需要额外的努力。浏览器一开始就实现了通过超链接的方式,支持多个 HTML 页面之间跳转。
Tim Berners-Lee, a British scientist, invented the World Wide Web (WWW) in 1989, while working at CERN. The Web was originally conceived and developed to meet the demand for automated information-sharing between scientists in universities and institutes around the world.
1989年,英国科学家蒂姆-伯纳斯-李在欧洲核子研究中心工作时发明了万维网(WWW)。万维网最初是为了满足世界各地大学和研究所的科学家之间自动分享信息的需求而构思和开发的。
Web 自它被发明开始,就已经是一种服务于跨团队(不同大学、不同科学组织)之间的沟通与协作的信息技术。
但是,朴素的页面跳转,往往会在页面过渡阶段产生白屏,在体验上不能满足我们的需求。
因此,当我们说“微前端”时,我们想要达到的目标是:
不同的前端团队,可以独立开发和部署他们的应用,满足自己的迭代需求
多个前端子应用之间的协作与切换,不应该产生不可接受的用户体验下降
1.2 微前端的类型
我们可以把微前端按照其拆解的颗粒度,分成:
页面级微前端(page-level):每个子应用独享一个页面,子应用之间的切换就是页面之间的跳转/切换。
区域级微前端(section-level):在同一个页面中,存在两类区域:
a. 共享区域,如顶部菜单栏、侧边栏等,由所有子应用共享。
b. 切换区域,通常作为主体内容呈现,子应用在该区域做局部切换。
页面级微前端(page-level)是浏览器的默认功能,但体验不佳;因此,当前大部分微前端框架前端开发,致力于区域级微前端(section-level),代表框架有 Qiankun,Single-Spa 等。
区域级微前端的主要实现思路,可以粗略概括如下:
代理或劫持 window 环境,让多个子应用及其依赖的前端框架,可以互不干涉地独立运行
每个子应用注册了“创建”与“销毁”等生命周期,等待主应用根据 url 去驱动和调度它们
区域级微前端(section-level)可以很好地解决某一类微前端场景(如复杂的后台系统),子应用恰好拥有相同的界面风格,甚至相同的 Layout,如顶部菜单栏、侧边栏等模块,只有内容主体部分有差异。
然而,在另一些场景中,我们可能仍然需要页面级微前端(page-level)。
子应用之间拥有不同的 UI 风格,甚至不同的 Layout,它们之间的切换,就是整页的切换,而不是局部的切换。
我们不希望子应用为了迎合区域级微前端(section-level)的接入要求,而做出巨大的调整,甚至改变开发方式。
子应用需要同时存在,并且可以在切换过程中,以滑入/滑出的动画方式转场,在回退过程中,可以自动保持滚动条位置等。
etc。
今天我们要介绍的——零界微前端,就属于上述页面级微前端(page-level),它克服了子应用切换过程的体验问题。
二、 零界介绍
2.1 设计理念
成本可控。接入成本不应该随着应用的接入数量增加而指数级地上升,接入 2 个应用和接入 100 个应用考虑的问题应该是一致的。
真正的技术无关。无论应用使用的是什么技术栈、渲染方式是SSR还是CSR、应用类型是SPA还是MPA,都可以无缝接入。
零耦合。微应用和主应用之间、微应用和微应用之间,完全没有依赖关系。应用的接入和退出不会对应用本身和已经接入的应用带来任何副作用。
2.2 基本工作原理
零界作为页面级微前端(page-level)解决方案,在架构上和区域级微前端(section-level)大体一致,但在实现方式上有所不同。
零界采用经典的基座应用 + 配置的方式来管理子应用。
在零界中,基座又叫做shell 。shell 只做两件事:存放微应用和调度微应用。
所有微应用都加载在iframe中,零界通过 shell 管理多个iframe的加载和切换。
然而,iframe 会带来路由不同步的问题。零界通过 history api 如 pushState 和 replaceState,将当前激活的页面的地址,同步到浏览器地址栏里的 location 中,保持了URL 一致。
与市面上微前端框架最大的不同是前端开发,在零界中没有生命周期、Event Bus等复杂的概念,而是监听微应用的跳转行为,通过将跳转记录存储在浏览器中, 把所有的微应用串联起来。每一次微应用的跳转,新的页面会以 iframe 的形式加载至零界微前端,并且不会立即释放之前微应用的内存,可以快速回退。为了避免过多的 iframe 导致页面卡顿,零界限制了 iframe的最大数量。
特点:
无需改造原有代码。技术栈无关,无需担心前端开发的难度。
几乎零接入成本。每个页面只需引入一个 script 文件,即可加入零界微前端机制。
无刷新切换页面。提供无刷新页面切换的 SPA 体验,给用户一致性的体验。
安全可靠。所有页面可随时退出零界微前端机制,回归原始状态。
状态同步。刷新页面不会丢失路由状态,页面回退更快展示,并保留前一页的滚动条以及页面状态。
隔离。完全隔离了每个页面的css和js,避免了各个应用之间的变量污染。
2.3 为什么是 iframe
构建区域级微前端(section-level)时,由于 iframe 使用简单、自带进程级别隔离等特性,许多开发者都曾考虑使用iframe 构建微前端,但最终都不约而同地放弃了这个方案。
让我们结合下图,再回顾下利用 iframe 构建区域级微前端(section-level)可能会带来的具体问题。
区域级微前端页面示意图
(1)DOM 割裂严重。蒙层只能覆盖其中一个微应用(一块蓝色区域),无法遮住整个应用(整个粉色区域);
(2)通信困难。不同的微应用同时存在于一个页面,微应用之间需要额外的通讯,而 iframe 只能通过 postmessage 传递序列化的消息,无法满足需求;
(3)加载慢。一个页面中通常存在多个微应用,微应用会频繁挂载、卸载,iframe 每一次加载都是一次上下文的重新构建;
(4)路由状态丢失。刷新页面后 iframe 会回到首次加载的状态;
可以看出,这些痛点是由 iframe 自带的特性导致的,不只是针对区域级微前端(section-level),而是使用 iframe 时要考虑的通用性问题。
现在,我们再站在页面级微前端(page-level)的角度,逐一思考上面的问题:
零界微前端页面示意图
(1)DOM 割裂严重;无需解决✅ 如上图所示,所有微应用的展示都是全屏的,不存在蒙层无法全局展开的问题。
(2)通信困难;无需解决✅ 各个微应用之间原本就属于完全不同的应用,所以并不用侧重于应用之间的通信。
(3)加载慢;无需解决✅ 在页面级微前端(page-level)中,每次进入页面只会加载一个微应用(iframe)。
(4)路由状态丢失;问题同样存在于页面级微前端
也就是说,我们只需要解决浏览器历史记录同步的问题,就可以最大化利用 iframe 的特性,这就是零界选择 iframe 管理微应用的原因。
三、 如何使用
3.1 基本使用
如上图所示,假设我们现在需要做到上面展示的home Page,page A,page B 和 page C 这4个页面无刷新切换的效果,应该如何实现呢?
如果他们是同一个应用的不同组件,则可以通过 React 或 Vue 的 TransiitonGroup 等组件快速实现。
但是,如果他们是 4 个朴素的HTML页面/应用,可能很难通过传统前端框架实现,甚至,大多数区域级微前端(section-level)也无法完成。
而在零界中,每个微应用都是全屏的,分别存放在 iframe 里,可以通过操作 iframe 的方式来操作微应用,就像把样式叠加在普通的 DOM 元素上一样。
零界针对 H5 页面模拟了 Native App 中 WebView 切换的机制,也就是上图的切换效果,接入零界即可开箱即用。
让我们来看下如何搭建零界微前端。
第 一 步,创建零界shell。
假设 4 个页面的地址分别为:
localhost:3000/demo/index.html
localhost:3000/demo/pageA.html
localhost:3000/demo/pageB.html
localhost:3000/demo/pageC.html
如上图所示,无需通过 npm/yarn 安装,也无需调用任何函数,只需要对一个普通的HTML页面做两个改动就可以完成 shell 的搭建:
(1)设置接入零界的微应用的匹配路径。
(2)引入零界shell脚本,引入后就可获得零界的能力。
第二步,接入零界。
在 4 个应用的 HTML中,分别在 head 标签里写入下面的代码
我们在接入零界的微应用上,也只做了两个改动:
(1)配置开启/关闭零界。
(2)引入零界 page 脚本。