慕课网从零打造微前端框架:实战“汽车资讯平台”项目
作者:互联网
提取码:3830
一.为什么放弃了qiankun
qiankun是基于single spa 搭建的一套微前端生态,但在调研使用的过程中,发现了以下几点不足:
- 对于React 深度定制项目来说,无法做到状态管理很好的传递
- 对于非标准的AMD、UMD、SystemJS 等加载方式的库会存在依赖问题(需要针对性改造)
- 多框架实现体积过大以及存在一定的调试成本
- 对现有项目具有比较大的改造成本
基于这些问题,小编一直在找业界有没有更好一点的方案。直到在github上偶然逛到 EMP微前端方案。
二.推荐尝试EMP方案的三大理由
1. 基于Webpack5 Module Federation
Module Federation [ˌfedəˈreɪʃn] 使 JavaScript 应用得以在客户端或服务器上动态运行另一个 bundle 的代码。
这其中的关键点是:
-
动态,包含两个含义:
-
按需,可以把一个包拆开来加载其中一部分;
-
运行时,跑在浏览器而非 node 编译时;
-
-
另一个 bundle 的代码,之前应用之间做共享是在文件级或 npm 包级 export 成员,现在可以在应用级 export 成员属性。
这样带来的好处是:
- js应用之间可以进行一些资源的共享,很适合做微前端
- 第三方依赖包的引入可以得到控制,从根本上释放了第三方依赖包的维护压力
因此,基于Webpack5 Module Federation去搭建生态的EMP微前端方案,会比基于single spa搭建的qiankun微前端方案来说,会显得更有底气,更加适应不同公司的业务。
(深入Module Federation原理学习可以点击 这里)
2. 完善的脚手架生态
从 EMP github上可以看到有这些丰富的脚手架和插件,以及针对react和vue主流框架的使用demo。
[图片上传失败...(image-7425e3-1604629294906)]
小编先帮大家体验一下使用感(激动得搓搓小手):
首先,安装脚手架@efox/emp-cli:( @efox/emp-cli使用教程)
npm i -g @efox/emp-cli
// 或者: yarn global add @efox/emp-cli
- 1.
- 2.
执行emp init
按照提示填写项目名称和选择template模板:
[图片上传失败...(image-85ae90-1604629294906)]
小编分别使用模板react-base和react-project生成empReactBase项目和empReactProject项目,这两个项目的根目录下,都有emp-config.js
文件,我们细看里面的配置:
比如empReactProject项目要使用empReactBase项目的一个UI组件,于是我们可以这样配置:
empReactBase项目暴露需要分享的组件资源出来:
[图片上传失败...(image-c3db91-1604629294906)]
empReactProject项目配置中引入empReactBase分享的资源:
[图片上传失败...(image-33b3d6-1604629294906)]
empReactProject项目使用empReactBase分享的资源:
[图片上传失败...(image-a3eb-1604629294906)]
于是我们访问empReactProject项目,就可以看到实际效果了。
另外,我们可以看到脚手架还有这些功能,具体使用可以参考教程:
[图片上传失败...(image-60f90-1604629294906)]
在初步使用中,体会到脚手架的功能是完整顺畅的,开发体验良好。而且官方在 wiki中也阐述了一系列指导如何落地的教程文档的发布计划:
[图片上传失败...(image-fb131d-1604629294906)]
还挺期待这些教程的,比如针对react和vue项目如何落地,特别是cocos2d 这种不使用react和vue的项目如何进行资源共享,小编赶紧star一波,期待更新。
3. 落地了多个线上项目,接入零成本
从EMP微前端方案中 Awesome,可以看到有该团队已经在公司内部成功落地了多个线上项目。
值得关注的话,接入的方式,几乎等于零成本!!!
私信了解到,这些Awesome案例,花费的接入时间非常短暂,而且不需要对现有项目做大改动,只需要引入EMP的配置,就可以收获微前端带来的价值硕果,收益显著。
看到这么多落地项目效果不错,可见该EMP微前端方案可执行度高,落地难度小且速度快,适合想快速拥抱微前端的团队使用,这也是小编推荐的重要原因之一。
什么是微前端
微前端是一种类似于微服务的架构,它将微服务的理念应用于浏览器端,即将 Web 应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。各个前端应用可以独立运行、独立开发、独立部署。
微前端的概念由ThoughtWorks于2016年提出,此后很快被业界所接受,并在各互联网大厂中得到推广和应用。
微服务与微前端有很多相似之处,都是希望将某个单一的单体应用,转化为多个可以独立运行、独立开发、独立部署、独立维护的服务或者应用的聚合,从而满足业务快速变化及分布式多团队并行开发的需求。微服务与微前端不仅仅是技术架构的变化,还包含了组织方式、沟通方式的变化。微服务与微前端原理和软件工程,面向对象设计中的原理同样相通,都是遵循单一职责(Single Responsibility)、关注分离(Separation of Concerns)、模块化(Modularity)与分而治之(Divide & Conquer)等基本的原则。
微前端的优缺点
优点
微前端如此受到重视,是由于其特点为开发团队带来了大量的收益。下面就分别描述一下其优点。
可以与时俱进,不断引入新技术/新框架
前端技术栈日新月异,推陈出新的速度绝对是冠绝群雄。如何在维护好遗留系统的前提下,不断引入新技术和新框架,提高开发效率、质量、用户体验,成为每个团队需要认真对待的问题。微前端可以很好的实现应用和服务的隔离,互相之间几乎没有影响,可以很好的支持团队引入新技术和新框架。
局部/增量升级
对于许多组织来说,追求增量升级就是他们迈向微前端的第一步。对他们来说,老式的大型单体前端要么是用老旧的技术栈打造的,要么就充斥着匆忙写成的代码,已经到了该重写整个前端的时候了。一次性重写整个系统风险很大,我们更倾向一点一点换掉老的应用,同时在不受单体架构拖累的前提下为客户不断提供新功能。
为了做到这一点,解决方案往往就是微前端架构了。一旦某个团队掌握了在几乎不影响旧世界的同时为生产环境引入新功能的诀窍,其他团队就会纷纷效仿。现有代码仍然需要继续维护下去,但在某些情况下还要继续添加新功能,现在总算有了解决方案。
到最后,我们就能更随心所欲地改动产品的各个部分,并逐渐升级我们的架构、依赖关系和用户体验。当主框架发生重大变化时每个微前端模块都可以按需升级,不需要整体下线或一次性升级所有内容。如果我们想要尝试新的技术或互动模式,也能在隔离度更好的环境下做试验。
代码简洁、解耦、更易维护
微前端体系下,每个小模块的代码库要比一个单体前端的代码库小很多。对开发者来说这些较小的代码库处理起来更简单方便。而且微前端还能避免无关组件之间不必要的耦合,让代码更简洁。我们可以在应用的限界上下文处划出更明显的界限,更好地避免无意间造成的这类耦合问题。
独立部署
就像微服务一样,微前端的一大优势就是可独立部署的能力。这种能力会缩减每次部署涉及的范围,从而降低了风险。不管你的前端代码是在哪里托管,怎样托管,各个微前端都应该有自己的持续交付管道;这些管道可以将微前端构建、测试并部署到生产环境中。我们在部署各个微前端时几乎不用考虑其他代码库或管道的状态;就算旧的单体架构采用了固定、手动的按季发布周期,或者隔壁的团队在他们的主分支里塞进了一个半成品或失败的功能,也不影响我们的工作。如果某个微前端已准备好投入生产,那么它就能顺利变为产品,且这一过程完全由开发和维护它的团队主导
组织更具扩展能力,其团队更加独立自治。
解藕代码库、分离发布周期还能带来一个高层次的好处,那就是大幅提升团队的独立性;一支独立的团队可以自主完成从产品构思到最终发布的完整流程,有足够的能力独立向客户交付价值,从而可以更快、更高效地工作。为了实现这一目标需要围绕垂直业务功能,而非技术功能来打造团队。一种简单的方法是根据最终用户将看到的内容来划分产品模块,让每个微前端都封装应用的某个页面,并分配给一个团队完整负责。相比围绕技术或“横向”问题(如样式、表单或验证)打造的团队相比,这种团队能有更高的凝聚力。
缺点
有得必有失,在引入微前端的过程中难免会引入一些新的问题。只不过我们认为这些风险都能控制在合理水平上,微前端终究还是利大于弊的。
重复依赖
不同应用之间依赖的包存在很多重复,由于各应用独立开发、编译和发布,难免会存在重复依赖的情况。导致不同应用之间需要重复下载依赖,额外再增加了流量和服务端压力。
团队之间更加分裂
大幅提升的团队自治水平可能会让各个团队的工作愈加分裂。各团队只关注自己的业务或者平台功能,在面向用户的整体交付方面,会导致对用户需求和体现不敏感,和响应不及时。
微前端应用场景
兼容遗留系统
经常会有团队需要在兼容已有系统的前提下,使用新框架去开发新功能。遗留系统功能已经完善,并且稳定运行,团队没有必要,也没有精力去将遗留系统重构一遍。此时团队如果需要使用新框架,新技术去开发新的应用,使用微前端是很好的解决方案。
应用聚合
大型互联网公司都会为用户提供很多应用和服务,如何为用户呈现具有统一用户体验的应用聚合成为必须解决的问题。而在大型商业公司内部,往往部署有大量的软件服务。如何为员工提供服务聚合,提供员工工作效率,成为企业内部IT建设的重中之重。前端聚合已成为一个技术趋势,目前比较理想的解决方案就是微前端。
团队间共享
不用应用之间往往存在很多可以共享和功能和服务,如果在团队之间进行高质量的共享成为提高研发效率的一条重要途径。微前端可以采用组件或者服务的方式进行团队间的技术共享。其低内聚高耦合的共享,使得高质量的共享成为可能。
局部/增量升级
一个大的产品由很多应用和服务组成,很多时候只需要对部分应用和服务进行升级。如果是单体应用,升级耗时长,风险高,影响可服务性。而前端可以只对需要的应用和服务进行升级,不会影响其他应用和服务。升级效率高,风险低,不影响其他应用和服务的可服务性。
微前端要克服的几个障碍
既然微前端具有如此多的优点,您是不是已经跃跃欲试,想要马上在团队里引入了呢?且慢,在引入微前端的过程中会遇到一些障碍,我们先看看会遇到那些障碍吧。
资源的隔离
由于存在不同应用各自定义CSS和全局变量的情况,应用聚合时需要考虑彼此之间的影响。应用JS沙箱和CSS隔离等相关技术,使各应用之间互不影响。
应用的注册
Html Entry 和 Config Entry,是关于如何注册子应用信息。
对性能的影响
按需加载、公共依赖加载和预加载,是关于性能的,这些很重要,否则虽然上了微前端,但性能严重下降,或者由于升级引起线上故障,就得不偿失了。
应用间通信
父子应用通讯,顾名思义,无需解释。
应用嵌套/并行
子应用嵌套 和 子应用并行 是微前端的进阶应用,在某些场景下会用到。
微前端实现的几种方式
路由分发式微前端
路由分发式微前端,即通过路由将不同的业务分发到不同的、独立前端应用上。其通常可以通过 HTTP 服务器的反向代理来实现,又或者是应用框架自带的路由来解决。
目前,通过路由分发式的微前端架构应该是采用最多、最容易实现的 “微前端” 方案。但这种方式实际上只是多个前端应用的聚合并不是一个完整的整体。每次用户从A应用跳转到B应用的时候,实际上是访问不同的html页面。
它适用于以下场景:
- 不同技术栈之间差异比较大,难以兼容、迁移、改造
- 项目不想花费大量的时间在这个系统的改造上
- 现有的系统在未来将会被取代
- 系统功能已经很完善,基本不会有新需求
使用iFrame创建容器
使用iframe标签嵌套将另一个HTML页面嵌入到当前页面中。iframe可以创建一个全新的独立的宿主环境,这意味着我们的前端应用之间可以相互独立运行。采用iframe有几个重要的前提:
- 网站不需要 SEO 支持
- 拥有相应的应用管理机制。
在采用iframe的时候,我们需要做这么两件事:
- 设计管理应用机制:在什么情况下,我们会去加载、卸载这些应用;在这个过程中,采用怎样的动画过渡,让用户看起来更加自然。
- 设计应用通讯机制:直接在每个应用中创建 postMessage 事件并监听,并不是一个友好的事情。其本身对于应用的侵入性太强,因此通过 iframeEl.contentWindow去获取iFrame容器内的Window对象是一个更简化的做法。随后,就需要定义一套通讯规范:事件名采用什么格式、什么时候开始监听事件等等。
自制框架兼容应用
不论是基于Web Components的Angular,或者是VirtualDOM的React 等,现有的前端框架都离不开基本的HTML元素DOM。
那么,我们只需要:
- 在页面合适的地方引入或者创建 DOM
- 用户操作时,加载对应的应用(触发应用的启动),并能卸载应用。
第一个问题,创建 DOM 是一个容易解决的问题。而第二个问题,则一点儿不容易,特别是移除 DOM 和相应应用的监听。当我们拥有一个不同的技术栈时,我们就需要有针对性设计出一套这样的逻辑。
尽管Single-SPA已经拥有了大部分框架(如 React、Angular、Vue 等)的启动和卸载处理,但是它仍然适合于微前端的加载和卸载。可以自己设计和实现一个微前端框架。虽然,这种方式的上手难度相对比较高,但是后期订制及可维护性比较方便。在不考虑每次加载应用带来的用户体验问题,其唯一存在的风险可能是:第三方库不兼容。
但是,不论怎样,与iFrame相比,其在技术上更先进。同时与iframe类似,我们仍然面对着一系列的不大不小的问题:
- 需要设计一套管理应用的机制。
- 对于流量大的toC应用来说,会在首次加载的时候,会多出大量的请求。
组合式集成:将应用微件化
组合式集成,即通过软件工程的方式在构建前、构建时、构建后等步骤中,对应用进行一步的拆分,并重新组合。
从这种定义上来看,它可能算不上并不是一种微前端——它可以满足了微前端的三个要素,即:独立运行、独立开发、独立部署。但是,配合上前端框架的组件 Lazyload 功能——即在需要的时候,才加载对应的业务组件或应用,它看上去就是一个微前端应用。与此同时,由于所有的依赖、Pollyfill已经尽可能地在首次加载了,CSS样式也不需要重复加载。
常见的方式有:
- 独立构建组件和应用,生成 chunk 文件,构建后再归类生成的 chunk 文件。(这种方式更类似于微服务,但是成本更高)
- 开发时独立开发组件或应用,集成时合并组件和应用,最后生成单体的应用。
- 在运行时,加载应用的 Runtime,随后加载对应的应用代码和模板。
标签:实战,慕课,框架,前端,独立,汽车资讯,应用,团队,加载 来源: https://www.cnblogs.com/ubkz/p/15169254.html