微前端——理论

2022-10-06 20:42:00 浏览数 (2)

天下大势,分久必合合久必分。大型组织的组织结构、软件架构在不断的发生变化。一款软件从最初的单一,进行不断的细化,最终变得庞大,从而不得不拆分到不同部门,出现多样化。然而在多样化的道路上,用户厌倦了一家公司的软件却要分散于不同的应用中,于是应用又再一次走向聚合。

***

一、微前端

1、什么是微前端

微前端类似于微服务,它将微服务的理念应用于浏览器端。

(1)微服务:把后端的功能进行了拆分,使用统一的网关进行调用。方便独立部署和维护升级, 不同的微服务,可以使用不同的技术去实现

微服务.png微服务.png

(2)微前端:有统一的加载器,各个子应用,也可以使用不同的框架。但是同一团队中,技术栈相同有利于管理和协作,方便子应用整合。

微前端.png微前端.png

***

对前端应用进行拆分,将不同的功能按照不同的维度拆分成多个子应用,实现应用的自治。微前端的核心在于拆, 拆完后再合!

电商系统微前端拆分.png电商系统微前端拆分.png

特点如下: (1)独立开发、独立部署 子应用可以分别让多个团队开发,部署的时候只需要更新我们希望更新的应用,整体不受影响 (2)单一职责 重点关注本应用的功能,降低耦合 (3)技术栈无关 每个团队可以自主选择技术栈,再接入主应用

2、为什么使用微前端

(1)老代码迁移 之前的老应用,已经稳定运行了,并且没有新功能,没有理由去重写这一整套,这个时候就可以使用微前端,直接整合到新应用中 (2)前端聚合 现在有很多这种情况,一家公司会提供一系列的产品,而用户并不想用这么多应用,在用户眼里,可能觉得明明是一家公司,用一个产品就够了,因此聚合也就成了一个趋势 (3)流行 因为流行去学习一项新技术,并没有什么问题,新技术意味着可以在一定程度上提升技术水平和技术影响力。但是,如果对于这样一个“流行”的技术,没有多加研究,就直接在项目中使用,难免会出现一些问题

3、微前端架构模式

(1)基座模式

通过一个主应用来管理所有子应用,他可以只是单纯的基座功能,也可以带有业务功能,一般业务都是核心部分业务,如用户登录、菜单管理等。只需要设计好对应应用加载机制,何时加载,何时卸载。

优点:难度小、方便实践 缺点:通用度低 例如:用户想访问A应用必须先加载主应用,然后才能加载A应用

(2)自组织模式

应用各管各,相互独立,各自拥有一个小型的基座管理功能,每个应用都可以是基座,从而每个应用有了更高的自主性,但是这样会导致出现很多重复代码。

优点:通用度高 缺点:设计难度大 例如:用户想要访问A应用,不需要加载其他应用,直接可以打开

4、微前端拆分方式

不合理的采用微前端,可能会带来很多问题,如前端基础设施不完善,会导致各个应用有大量的重复代码。另外一个简单的业务,是否真的有必要成为一个单独的应用,将一个整体拆分成了很多个小应用,是否真的能提高效率,还是变得更加不便维护了呢。面对这些问题,我们要采取合适的拆分策略。

(1)按照业务拆分 在一个系统中,如果同时存在多个系统,如订单系统、库存系统、物流系统等,每个系统有自己的业务,关联也不是很紧密,那么拆分起来就很轻松了。 但是如果业务本身耦合严重,比如一个操作人员,需要同时操作这三个系统,那么拆分起来就不是很容易了。 因此,对于由业务性质决定的应用,只能根据业务是否隔离来进行拆分。 (2)按照权限拆分 比如一个网站有前后台两个系统,前台系统只能用户使用,后台系统只能管理员使用,那么就可以拆分开来。 (3)按照变更的频率拆分 在一个应用中,并不是所有部分都在不断迭代,有些功能可能上线后因为用户量少,几乎不修改。若是将应用中频繁变更的部分拆分出来,不仅更容易维护,还可以减少频繁的更改给其他部分带来的问题。 (4)按照组织结构拆分 这种更适合同一个应用,几个团队一起开发,按照团队来划分不同的前端应用。但是如果一个团队维护着多个业务模块,随着业务的增多和变复杂,还是需要进一步拆分的。 (5)跟随后端微服务拆分 一旦后端拥有相关服务,前端也可跟随拆分,但是后端拆分方式并不全部适用于前端,还是要具体问题具体分析。

二、微前端实现方式

1、服务端集成

通过Nginx配置反向代理来实现不同路径映射到不同应用

代码语言:txt复制
    server {
        listen 80;  #监听80的服务端口
        server_name localhost;  #监听的域名
        location /{
            root /base;
        }
        location /vue-app {
            proxy_pass http://127.0.0.1:3000/micro-app/vue-app;
            add_header 'Access-Control-Allow-Credentials' 'true';
            add_header 'Access-Control-Allow-Origin' '*';
        }
        location /react-app {
            proxy_pass http://127.0.0.1:4000/micro-app/react-app;
            add_header 'Access-Control-Allow-Credentials' 'true';
            add_header 'Access-Control-Allow-Origin' '*';
        }
    }

优点:成本比较低,可以实现独立开发和部署 缺点:丢掉一部分的 SPA 体验,每次跳转都会刷新整个页面

2、构建时集成

在构建时将拆分开的子应用打包成一个应用,使用 npm 包的方式加入到主应用

代码语言:txt复制
{
  "dependencies": {
    "@vue-app": "^0.0.1",
    "@react-app": "^0.0.1",
  }
}

优点:独立开发,保留了 SPA 体验 缺点:无法独立部署,且部署的成本非常高,一个子应用更新就需要重新构建整个应用

3、运行时集成

使用 iframe,通过改变 iframe 的 src 属性来加载对应的子应用

代码语言:txt复制
<iframe src="https://vue-app/index.html"></iframe>

优点:简单易上手,接入成本低;自带沙箱机制 缺点:url 不同步,浏览器刷新 iframe url 状态丢失、后退前进按钮无法使用;UI 不同步,DOM 结构不共享,一个iframe 中的元素只能在当前 iframe 中展示;全局上下文完全隔离,内存变量不共享。iframe 内外系统的通信、数据同步等不方便;慢,每次子应用进入都是一次浏览器上下文重建、资源重新加载的过程

三、微前端开源方案

Single-SPA:用于前端微服务化的JavaScript前端解决方案 (本身没有处理样式隔离、js执行隔离) 实现了路由劫持和应用加载;但是加载文件需要自己构建script标签,但是加载文件需要自己构建script标签,主应用必须得手动加载子应用打包好的lib库文件,如果子应用比较多,比较麻烦,不灵活;样式不隔离,父子应用会相互影响,没有js沙箱机制,共用同一个window。

qiankun:基于Single-SPA, 提供了更加开箱即用的 API (single-spa sandbox import-html-entry),它做到了技术栈无关,并且接入简单。主框架不限制接入应用的技术栈,微应用具备完全自主权,微应用仓库独立,前后端可独立开发,部署完成后主框架自动完成同步更新,每个微应用之间状态隔离,运行时状态不共享。

以上两种是现阶段比较常用且较成熟的方案,后期文章中会详细介绍,除此之外,还有Piral、Luigi,以及腾讯的微前端oteam和无界(基于iframe)以及Hel微前端,美团的Bifrost,字节的lModern.js和lGarfish,感兴趣的可以了解一下。

四、最后

实施微前端并不容易,我们要深入框架原理,了解各种相关的实现,才能封装出适合自己的方案。尽管都有一些缺陷,不一定是最好的实践,但随着技术的发展,一定会出现更好的方式,来实现目标。

0 人点赞