将
Web
应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。
前言
正如文章开头所引用,微前端是将 Web
应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。这个理念类似于后端的微服务,第一次提出微前端概念的是 ThoughtWorks 公司。
它正是借鉴微服务的概念来应用在前端上,将一个巨大的前端工程拆分成一个的小工程,这些小工程具备独立的开发和运行能力,而整个系统就由这些小工程协同合作。
微服务 | 微前端 |
---|---|
一个微服务就是由一组接口构成,接口地址一般是 URL。当微服务收到一个接口的请求时,会进行路由找到相应的逻辑,输出响应内容。 | 一个微前端则是由一组页面构成,页面地址也是 URL。当微前端收到一个页面 URL 的请求时,会进行路由找到相应的组件,渲染页面内容。 |
后端微服务会有一个网关,作为单一入口接收所有的客户端接口请求,根据接口 URL 与服务的匹配关系,路由到对应的服务。 | 微前端则会有一个加载器,作为单一入口接收所有页面 URL 的访问,根据页面 URL 与微前端的匹配关系,选择加载对应的微前端,由该微前端进行进行路由响应 URL。 |
Why
为什么前端也需要 "微服务" 的概念呢?
文章的标题中说到,微前端是一种插拔式架构,可以用于SaaS产品定制化。那我们主要从以下几个方面来简述下为什么选择微前端:
-
打包速度:由于某些项目可能比较大,业务上百,接口上千,即使我们使用多线程编译,打包过程也需要5-20分钟,尤其是在上线前调试、修改bug或者线上部署后出现问题时,可能每修改一点bug就需要打包一次。甚至出现修改2分钟,打包5分钟的现象,大大影响工作效率。
-
页面加载速度:我们将资源通过
CDN
、gzip
和按需加载处理后其实基本已经可以优化很多,但是如果通过微前端的技术,我么可以进一步在SPA
的首屏渲染上进行优化。 -
多人多地协作:这里我们拿美团HR系统举例,他们的系统由三个团队负责,甚至是不同区域,如果在同一个仓库进行开发,由于沟通和一些其它未知因素造成冲突的几率将会非常大,从而导致代码提阻塞,采用微前端则可将风险减少到每一块业务工程上。
-
SaaS产品定制化:物联网的日益成熟,SaaS定制化的服务也越来越常见,采用微前端技术则可以按功能或者业务进行拆分而不影响其它功能模板的运行,这样便可以更好的增加或者删除功能业务,做到真正的插拔式定制。
-
产品拆分:上面定制化也说到插拔式,假设我们的产品有
['A', 'B', 'C', 'D']
四个功能模块,客户只需要要前三个,那我们只需将D
功能模块进行 拔除 即可。或者说需要将A
业务功能独立成一个子产品,由于微前端每一块都是可以独立运行的,所以并不会影响整体的业务。
优缺点
在上面的为什么要使用微前端中我们已经简述了一部分好处,下面我们再列举下微前端的其他优点和缺点。
优点
- 单一职责:独立部署不同的服务
- 应用自治:实现自治团队,具备独立迭代和创新的能力
- 技术栈无关:能够围绕业务部门或产品来打造团队,根据不同的业务采用不同的技术栈
缺点
- 产品拆分基于基础设施的构建,一旦大量应用依赖于同一基础设施,那么维护变成了一个挑战
- 拆分的粒度越小,便意味着架构变得复杂、维护成本变高
- 技术栈多样化,容易混乱
- 跟踪、调试和维护整个系统的问题
所以在使用微前端技术的时候,要充分考虑是否需要?否则导致弊大于利而得不偿失。
实现方式
实现微前端的方式有很多种,不同的方式适用于不同的使用场景,当然也可以组合一起使用。那么,就让我们来一一了解一下,为以后的架构做一些技术铺垫。
- 使用
HTTP
服务器的路由来重定向多个应用 - 在不同的框架之上设计通讯、加载机制,诸如
Mooa
和Single-SPA
- 通过组合多个独立应用、组件来构建一个单体应用
- 使用
iFrame
及自定义消息传递机制 - 使用纯
Web Components
构建应用 - 结合
Web Components
构建
HTTP
路由分发式微前端,即通过路由将不同的业务分发到不同的、独立前端应用上。其通常可以通过 HTTP
服务器的反向代理来实现,又或者是应用框架自带的路由来解决。
这种方式是最易采用的方案,但是这种方式看上去更像是多个前端应用的聚合,即我们只是将这些不同的前端应用拼凑到一起,使他们看起来像是一个完整的整体。但是它们并不是,每次用户从 A
应用到 B
应用的时候,往往需要刷新一下页面。
以 Nginx
为例:
http {
server {
listen 80;
server_name www.phodal.com;
location /api/ {
proxy_pass http://http://172.31.25.15:8000/api;
}
location /web/admin {
proxy_pass http://172.31.25.29/web/admin;
}
location /web/notifications {
proxy_pass http://172.31.25.27/web/notifications;
}
location / {
proxy_pass /;
}
}
}
使用场景:
- 不同技术栈之间差异比较大,难以兼容、迁移、改造
- 项目不想花费大量的时间在这个系统的改造上
- 现有的系统在未来将会被取代
- 系统功能已经很完善,基本不会有新需求
IFrame
IFrame
大家应该比较熟悉了,IFrame
可以创建一个全新的独立的宿主环境,这意味着我们的前端应用之间可以相互独立运行。不同应用通过 postMessage
进行通讯,可以根据自己团队进行通讯规范的制定。
使用场景:
- 系统集成第三方系统
- 系统集成不同团队的系统
使用框架
现在比较流行的前端框架都是基于 DOM
,那么我们只需在适当的地方适时的将所需的 DOM
插入进来即可。现阶段比较成熟的框架是 Single-SPA
,兼容大部分框架(如 React
、Angular
、Vue
等框架)。我么也可以根据自己的业务需要进行二次封装,比如针对 Angular
的 Mooa
和基于 umi
的 qiankun
。
这边附上 Single-SPA
的一个简单 Demo
,还是比较简单的:传送门
组合式集成
组合式集成,即通过软件工程的方式在构建前、构建时、构建后等步骤中,对应用进行一步的拆分,并重新组合。
这种方式有一个限制就是:必须使用一个框架,制定代码规范
使用方式:
- 独立构建组件和应用,生成 chunk 文件,构建后再归类生成的 chunk 文件。(这种方式更类似于微服务,但是成本更高)
- 开发时独立开发组件或应用,集成时合并组件和应用,最后生成单体的应用。
-
在运行时,加载应用的 Runtime,随后加载对应的应用代码和模板。
microfront_end.jpg
纯 Web Components
不知道 Web Components
可以看下这篇文章:Web Components
每个组件通过 link
标签引入:
<link rel="import" href="components/di-li.html">
<link rel="import" href="components/d-header.html">
随后,在各自的 HTML
文件里,创建相应的组件元素,编写相应的组件逻辑。一个典型的 Web Components
应用架构如下图所示:
使用纯 Web Components
的难度:
-
重写现有的前端应用。是的,现在我们需要完成使用
Web Components
来完成整个系统的功能。 -
上下游生态系统不完善。缺乏相应的一些第三方控件支持,这也是为什么
jQuery
相当流行的原因。 - 系统架构复杂。当应用被拆分为一个又一个的组件时,组件间的通讯就成了一个特别大的麻烦。
-
新一代DOM。并不是所有的浏览器,都可以完全支持
Web Components
。
结合 Web Components 构建
虽然现阶段使用 Web Components
构建应用还不太现实,但是这是一种未来的方向,未来我们可以采用这种方式。
使用方式:
-
在 Web Components 中集成现有框架。现有的
Web
框架已经有一些可以支持Web Components
的形式,诸如Angular
支持的createCustomElement
,就可以实现一个Web Components
形式的组件: -
集成在现有框架中的 Web Components。将组件直接构建成
Web Components
形式的组件,随后在对应的诸如,如React
或者Angular
中直接引用。
复合型
采用上述若干方法组合在一起。
选型
这边推荐一篇文章,比较详细的介绍了上述方法的选型问题:传送门
总结
在产品层面上,“微前端类单页应用”打破了独立项目的概念,我们可以根据用户的需求自由组装我们的页面应用。在团队方面上,我们可以进行垂直拆分,一个小组负责一块业务,职责更明确。
最后祝愿大家事业步步上升~
网友评论