前言


一个完整的产品往往都是从一个个小的功能模块进行开发,然后经过一系列的迭代更新。功能模块越来越多,所需要的依赖包也会越来越多,这时候的产品就会越来越庞大。这里的庞大指的是构建效率低下、dev-server 占用内存大甚至内存泄露、维护成本急剧增加

如果要升级或者更换系统的开发框架的话需要投入大量的工作量。并且有些系统的功能并不是一直在迭代开发,而是在某个版本之后就不会持续开发。但是在系统持续集成中依然要将这部分代码添加进来。这时候旧代码的兼容也成了一个需要解决的问题。因为随着版本的迭代,依赖包的版本也会一直升级,但是旧代码的依赖包可能只局限于某个版本之下。种种

的问题都亟待解决。

01 WHAT


首先以下面的场景为例子:  

乾坤微服务中activeRule 乾坤微前端原理_迭代


这是一个基础的后台系统界面。通常来说左侧的 菜单栏随着功能的迭代更新,新的功能模块也会越来越多。假设现在需要新增一个功能模块,这个功能模块我们已经在另外一个独立的项目中实现了。我们需要将这个功能从这个项目中迁移到我们的产品之中。 一个比较笨的办法就是直接把新项目这个页面的代码拷贝过来,但是这样会有个问题,万一新项目中开发框架和产品中的开发框架不一致或者版本有差异、组件库等不同

,以及别人的页面加载之前操作(路由拦截,鉴权等)我们都需要拷贝过来,更重要的问题是,如果代码有更新,我们如何做到同步更新。 从代码的持续化来说,直接拷贝页面代码不是一种可行的道路。我们需要将这个功能模块作为一个单独的应用来去开发,然后暴露出相关的接口和功能。通俗来说就是将产品中的各个功能模块作为一个个独立的应用系统,然后将这些模块再整合起来组装成完整的产品。这就是最基础的微前端的概念。

Techniques, strategies and recipes for building a modern web app with multiple teams that can ship features independently. --  Micro Frontends( 微前端是一种多个团队通过独立发布功能的方式来共同构建现代化 web 应用的技术手段及方法策 略。) 在这里先提一下后端上的微服务。 微服务

是为了解决庞大的后端服务带来的变更与拓展方面的限制,而将一个大型的服务应用分割成若干个颗粒度较小的可独立开发、测试及部署的单个子应用。微前端的理念和微服务很相似。本质上都是为了将复杂庞大的前端应用拆解成一个个可以独立开发的部署的功能模块,并通过暴露相关的接口和功能来将各个功能模块进行连接。


02 WHY


一个巨型应用系统可能会出现的问题:

  • 随着功能模块越来越多,各种npm包也会越来越多,打包的时候会越来越慢。npm包的升级也会带来一些其他不可预见的问题,比如不兼容等问题
  • 多人员同时进行一个模块的开发会导致代码规范不一致所带来的一系列问题。例如在合并代码时会存在大量冲突
  • 组件或者框架升级时需要投入大量人力和时间去进行开发,相当于重新开发一个新的系统
  • 一个成熟的产品是有多样化的功能模块来组成的。但是在某些特定应用场景中也许我们用不到所有的功能而只是需要其中的某些功能,如果按照一般做法来做的话需要剥离出相关模块代码进行单独维护 


大体的问题就是这几个,微前端的提出也正是为了解决这些问题。将一个大型的应用拆分成各个独立开发部署的应用子系统,这些子系统能够进行复用并且和其他模块进行解耦合。如果需要某些特定模块的话只需要将单独的模块进行独立打包部署进行交付即可,每个子系统独立于主系统之外又能为主系统进行服务。

总结一下,使用微前端架构去进行开发的 好处:


  • 灵活性高,功能模块作为一个单独的服务可以进行单独部署。功能模块之间互不影响,升级简单。不同项目之间的功能模块可以拆分组装成一个新的应用系统
  • 可以复用或嵌入已有的功能模块及页面,不同功能模块可以采用不同的开发框架并且可以运行在不同的环境之中


同时微前端的 不足

也显而易见: 上手难度较高,同时对于简易的系统来说采用这种方案去进行开发会产生包括人员和时间上的资源溢出。


乾坤微服务中activeRule 乾坤微前端原理_乾坤微服务中activeRule_02


 


03 HOW


微前端的实现目前有这几种方式: (1)iframe

其实严格意义上来说 iframe 不属于微前端的概念范畴而是属于‘类单页应用型’的实现方案 。 i frame 提供了天然的 js / css 沙箱 , 将外部应用和内部应用完全隔离开来 。 实现方式比较简单 , 但是 同时局限性也高 。 iframe的局限性体现在:


  • iframe的区域需要明确大小,样式不容易控制
  • 对于浏览记录不能够保存导致页面刷新时不能被浏览器记忆
  • iframe功能之间的跳转是无效的
  • 兼容性不高


对于以上的局限性来说,大多都已经有了解决方案。具体的解决方案可以自行查阅,在这里就不再详述。 (2)single-spa

single-spa是一个用于前端微服务化的JavaScript前端解决方案,它允许多个应用程序在一个页面应用程序中共存,本质上是一个javascript库。现在流行的单页应用系统就是一个spa页面。那单页应用系统和微前端架构下的应用系统有什么区别?

  • 单页应用系统架构:

乾坤微服务中activeRule 乾坤微前端原理_迭代_03

  • 微前端架构:

乾坤微服务中activeRule 乾坤微前端原理_乾坤微服务中activeRule_04


实现一套完整的微前端架构需要由四个部分组成:


  • 主应用:上图中的base模块,一般是所有子应用模块所共用的公共部分。
  • 子应用:众多展示在主应用内容区的应用。
  • 包装器:将现有的应用包装供给加载器使用。
  • 加载器:整个架构的核心部分,它的作用是用来调度子应用,决定何时展示哪个子应用。


简单点来说,整个微前端工作的流程就是用户访问index.html后,浏览器访问加载器中的js文件,然后注册配置文件中配置的各个子应用后,首先加载主应用(菜单等),再通过路由判定,动态远程加载子应用。而single-spa是一个在前端应用程序中将多个javascript应用集合在一起的框架,主要充当 包装器

的角色。

qiankun (乾坤)框架


qiankun 是蚂蚁金服开源的一款框架,它是基于 single-spa 来进行封装的库,它提供了开箱即用的API接口供使用。可以无缝接入React/Vue/Angular/JQuery 还是其他等框架,同时还采用了HTML Entry的接入方式,实现了js/css的沙箱隔离。后续文章将介绍如何搭建一个基于qiankun+vue开发的微前端实践样例。

  总 结

微前端的概念是近几年才提出来的,其目的旨在解决巨石应用在开发过程中产生的种种问题,但是它并不是万能的。在用微前端去实践一个具体的项目的时候遇到了一些问题,具体的解决方案留到下期实践篇再一一详述。上述文章内容如若有失偏颇,还请教正。

作者:符致望