一个写给初学者如何搞微前端的「从入门到放弃专栏」

前言

大家好,我是易师傅,从这篇文章开始,我将会开设一个新的专栏《微前端从入门到进阶》,大家感兴趣的可以去关注一下;

细看当下,微前端相关文章已经在网上数不胜数了,但是其实很多讲的会比较细而不全,多而杂乱;其中较多的都是从代码中去衍生出来的一些文章,没有做到从新手的角度去系统的讲解微前端的;

微前端.png

该系列是一个由浅入深让你从微前端的 选型、定型、造型 三个方面出发,全面深入了解微前端的原理及理念,如何搞定一个企业级微前端服务从提出到落地的;

文章全文 4526 字数,阅读全文预计 8-10min

一、认识微前端

微前端(Micro-Frontends) 并没有定义框架或 API,它其实是一个类似 微服务架构 的概念;将 微服务 的概念扩展到了前端世界;

说微服务可能有些前端同学会感觉陌生,以咱们前端的角度一句话概括就是: 将您的大型前端应用拆分为多个小型前端应用,这样每个小型前端应用都有自己的仓库,可以专注于单一的某个功能;

需要强调的是,尽管我们将前端应用拆分为多个项目,但它们最终还是会被集成到一个单页前端应用程序中;因此,通过使用微前端架构,您不会在用户体验上有任何损失,只会有过之而无不及;

同时我们需要了解的是 微前端(Micro-Frontends) 一词是在 2016 年底在 ThoughtWorks Technology Radar 中首次被提及。

后端微服务架构图

微前端2.png

详细的 微服务架构图 会比这个复杂的多,但是为了照顾到前端的同学,所以大致能够明白个大致所以然即可;

说白了就是后端把一个巨型的后端应用拆分成多个微服务应用,具体好处这个就不多说了,因为下面微前端的优势会讲到;

前端微前端架构图

微前端(1).png

通过这张图,我们就可以很明显的看得出来微前端架构就是在一个前端应用中塞进去多个子前端应用,这样就构成了最简单的微前端概念,也是最核心的概念;

二、为什么要用微前端?

1. 在技术上的灵活选择

我们知道微前端的概念就是把一个大型项目拆分成多个小型项目,所以我们针对多个小型项目在技术上的选择就有了多样性,可以选择适合单个项目或者升级单个项目的新技术,且无需与其他团队进行沟通协调;

同时我们的 主应用基座技术单个微应用的技术 都有技术的自主选择权;

1513878936981.png

2. 更快的且独立的部署

我们明白一个项目在发布到生产环境时,是需要进行构建打包的;而且项目越大,构建所需的时间就越长;

虽然 WebpackParcel 以及 Vite 等打包工具已经竭尽全力的通过使用多线程和缓存等方法来提高打包的性能,但是这只是解决基本问题的权宜之计;

咱们就会发现即是有这些性能上的改变,只要随着您项目的持续扩大,那么构建的效率也会跟着下降;

所以通过将您的项目拆分成多个小型项目,每个小型项目都可以 独立部署构建 您的项目,无论您的项目如何增长,每个项目都会快速的构建;

微前端(2).png

3. 团队代码的相互隔离

根据微前端的概念,单个小型项目源代码会很少,这些较少的小型项目仓库对于开发人员来说往往会更加简单,且更容易上手;特别是在某些情况下一些不恰当的 耦合组件 所产生带来的复杂性,所以一个更简单且解耦的代码库我们无论如何都要去完成他;

正是因为微前端 简单化解耦 了我们的项目,所以我们每个 小型项目仓库 都会独立的去运行,并且运行时的状态是不共享的;

4. 并行开发和团队的自治

因为我们将项目拆分成了多个小型项目,那么我们就可以把每一个小型项目交个一个独立的团队去负责开发,这样在大多数的情况下,这些个独立的团队其实是不需要了解彼此的任何信息的,所以这个并行开发就会使我们的开发效率得到提升;

同时因为我们每一个小型项目都拥有一个独立的团队,所以他们能够有效且快速的从用户角度出发,围绕业务功能去做垂直开发,而不是围绕技术去做扩展,这样也会给团队带来更高的 凝聚力

微前端(3).png

5. 项目的增量升级

我相信一个成熟且稳定的大项目,一定有一个 庞大且臃肿的代码仓库,那么我相信您在此基础上做一些业务上的修改以及扩展一定是极其难受的,在内心想了无数次的重构,只是苦于历史遗留原因以及业务的稳定性而一直难以下手;

这不微前端就来了吗,他不仅可以让你 尝试新技术的红利,也能让你 无缝升级您的项目;因为微前端最重要的概念就是拆分,拆分成多个小型项目,这样我们在对我们的架构、依赖以及用户体验进行重构时,可以做到拆分部分功能增量升级,从而不会影响到其它未升级的部分;

所以微前端其实也是一种非常实用的去实施渐进式重构的架构

总结

简而言之,微前端 就是将一个大而可怕的项目拆分成多个更小、更易于管理的小型项目,然后明确它们之间的依赖关系;并且 我们的技术选择、代码库、团队和发布流程都应该能够相互独立地运行和升级,而无需过度耦合协调

一图总结微前端的价值

微前端(4).png

三、常见的微前端解决方案对比

1. 使用 HTTP 服务器(Nginx)的路由来重定向多个微应用

其实这也可以理解把一个大型项目拆分成多个微模板应用,每个微模板应用就代表一个前端服务,然后通过 Nginx 配置代理映射到不同的子模板应用上,这也叫路由分发式微前端,是一个非常古老且传统的方法;

细心的同学会发现这种方式看上去更像是多个前端应用的聚合,即我们只是将这些不同的前端应用拼凑到一起,使他们看起来像是一个完整的整体。但是它们并不是,每次用户从 A 应用到 B 应用的时候,往往需要刷新一下页面。

优点: 简单、快速、易配置

缺点: 在切换应用时会触发浏览器刷新,影响体验

2. 使用 iframe 及自定义消息传递机制

iframe 作为一个非常古老的,人人都觉得很普通的技术,却一直都很管用。

就其性质而言,iframe 可以轻松地从独立的子页面构建页面。它们还在样式和全局变量方面提供了很好的隔离度,不会相互干扰。

优点:

  1. 实现简单: 子应用之间自带沙箱,天然隔离,互不影响
  2. 技术不限制: 可以各自使用完全不同的前端框架;
  3. 消息传递: 只要每个 iframe 来自同一个来源,可以使用 Window.postMessageAPI 来进行消息传递;

缺点:

  1. Bundle 的大小各异: 构建时也不能提取公共依赖关系;
  2. 无 SEO: 众所周知 iframe 对 SEO 是毁灭性的打击,单这一条即可否定该方案了;
  3. URL 状态不同步: iframe 的页面 url 中的状态信息并不能同步到父窗口,无法使用浏览器的前进后退功能;
  4. DOM 结构不共享: iframe 的页面布局只针对于 iframe 窗口(例如:全局弹框无法给出合理布局);
  5. 全局上下文完全隔离,内存变量不共享: iframe 内外系统的通信、数据同步等需求,主应用的 cookie 要透传到根域名都不同的微应用中实现免登效果;
  6. 慢: 每次微应用进入都是一次浏览器上下文重建、资源重新加载的过程;

3. 使用纯 Web Components 构建应用

Web Components 是一个 Web 标准,所以像 Angular、React/Preact、Vue 或 Hyperapp 这样的主流 JavaScript 框架都支持它们;

你可以将 Web Components 视为使用开放 Web 技术创建的可重用的用户界面小部件,它或许会是 Web 组件化 的未来。

优点:

  1. 拥有自己独立的 Scripts 和 Styles,以及对应的用于单独部署子应用组件的域名;
  2. 代码的可读性变得非常清晰,组件资源内部高内聚,组件资源由自身加载控制;

缺点:

  1. 浏览器和框架的支持不够: 需要更多的 polyfills 从而影响到用户页面的加载体验;
  2. 重写现有的前端应用: 我们需要在整个前端应用上把它们全部转换成 Web Components;
  3. 系统架构复杂: 当应用被拆分为一个又一个的组件时,组件间的通讯就成了一个特别大的麻烦
  4. 社区不够活跃: Web Components 还没有真正流行起来,可能很快亦有可能永远也不会;

4. Module Federation 模块联邦

webpack5 新增的 Module Federation(模块联邦)功能,他可以帮助将多个独立的构建组成一个应用程序,不同的构建可以独立的开发与部署,利用模块联邦我们可以在一定程度上去实现微前端。

优点:

  1. 开箱即用:你只需要执行几行命令即可拉取相应的模板代码并把项目跑起来,包括基座应用和微前端应用,无需处理构建工具的复杂配置;
  2. 独立开发与部署:基于提供的代理工具,微应用开发者在单独开发微应用时,无需启动基座或者其它微应用;
  3. 去中心化: 因为采用的是模块共享,所以不用使用中心基座的概念;
  4. 组件共享: 与 npm 发包类似的组件共享管理;

缺点:

  1. 无法沙箱隔离: 需借助其它工具和框架才能做到应用层面的隔离;
  2. 技术单一: 仅限使用 webpack5 版本以上;
  3. 代码封闭性高: 依旧需要做npm那一套管理和额外的拉取代码,还不如直接 npm 复用方便;
  4. 拆分粒度需要权衡: 共享的 lib 无法做到 tree-shaking;
  5. 依赖前置: 导致时间加载变长;

5. 组合式应用路由分发(中心基座方案)

当下微前端主要采用的是 组合式应用路由方案,该方案的核心是 主从 思想,即包括一个基座(MainApp)应用若干个微(MicroApp)应用

基座应用大多数是一个前端SPA项目,主要负责 应用注册,路由映射,消息下发 等,而微应用是独立前端项目,这些项目不限于采用 React,Vue,Angular 或者 JQuery 开发,每个微应用注册到基座应用中,由基座进行管理,但是如果脱离基座也是可以单独访问,基本的流程如下图所示:

微前端5-1.png

优点:

  1. 技术不限制: 可以各自使用完全不同的前端框架;
  2. 无感切换: 因为是一个 SPA 项目,所以体验极佳;
  3. 利于SEO
  4. 独立开发与部署
  5. 微前端优势几乎都有

缺点:

  1. 沙箱不隔离: 也就是 js 与 css 样式会出现冲突的问题

6. 自由框架组合模式(复合型)

因为上述的几种方案都存在一定的优缺点,所以顾名思义咱们可以发挥方案的优势以及结合自己的项目来进行自定义的方案的组合模式,自定义一个更适合自己项目的微前端框架;

  1. 就好比完美解决沙箱隔离的 qiankun.js 就是基于 中心基座方案去做的一个升级;
  2. 还有比较完美的框架如:micro-appEMP微前端等框架都是采取了以上的一种或多种方案的组合;

这就不多介绍了,会在后面的章节再详细的介绍;

四、如何判定公司项目是否需要微前端?

1. 巨石应用

其实如何判定公司项目是否需求使用微前端,也很简单,主要查看一点项目是不是一个巨石应用,如何去定义一个巨石应用,我们从下面几方面可以定义;

  1. 部署频繁:每一次细微的修改都需要整个部署应用;
  2. 部署时间长:每次部署的时间渐渐进入10min的行列;
  3. 加载缓慢;
  4. 开发效率随着应用变大而低下;

2. 多个项目间跨应用模块共享

如果存在在多个项目中共同使用共享一套模板的情况,说白了就好比 webpack5 的模块联邦 功能,那么这个时候是不是需要使用更加合适的微前端方案来实现会比较合适呢?

3. 有拆分出多个独立的子系统,独立部署维护的需求

因为业务团队的分离,以及某个功能的扩展,我们需要把当前应用拆分成多个各个业务团队的子应用,做到团队自治,互不关联,同时这个并行开发也会使我们的开发效率得到提升;

4. 受限于技术导致开发缓慢

熟悉 ES6 的同学应该都知道,ES6开发与传统 Javascript 和 Jquery 的开发效率还是有蛮大的区别的,所以当公司的研发进度很明显的受限于旧技术,那么这个时候你还在犹豫什么呢?还不赶紧支棱起来!

五、如何说服领导去用微前端?

1. 从身份角度

之所以把这个放在第一条,是因为在企业中一个人说话分量权重其实很大程度是取决于他自身的身份的;

  • 就好比如果你是领导的心腹,那么不用看下面两条了,就可以直接执行了;
  • 如果你在你团队中只是一个举足轻重的角色,那么你就不得不去修饰自己,以及考量你的方案给团队所带来的的风险了,实施的好与坏直接取决于你在这个团队中后面的走向;

所以具体是否实施,仁者见仁智者见智吧 ~

2. 从微前端优势入手

微前端所带来的的优势,在上面其实已经讲的很详细,所以无论你是怎样的身份还是建议与领导做个较为详细的推动计划;

3. 把当前项目的缺点放大化

如果你想真正的想实行你的微前端大计,那么缺点的放大化是必不可少的一环,只有让领导看到了项目的弊端,他才能从中醒悟;

用实际例子以及实际代码举例,可以从 研发时间过长部署时间过长技术老旧 等方面去说服;

当然如果遇到 比较执着 或者 一层不变 的领导,我觉得你应该想想自己适不适合这个团队了;

最后

最后说一句:用新技术,更多的不是因为先进,而是适合。 该系列是一个由浅入深让你从微前端的 选型、定型、造型 三个方面出发,全面深入了解微前端的 原理及理念,如何搞定一个企业级微前端服务从提出到落地的专栏;

感兴趣的朋友可以关注我的专栏《微前端从入门到进阶》,想与更多前端大佬交流,可以进入我的掘金主页加 vx 吹水;

微前端.png

我正在参与掘金技术社区创作者签约计划招募活动,点击链接报名投稿

猜你喜欢

转载自juejin.im/post/7118712142764703751