前端微服务
介绍
什么是前端微服务?我们知道,近些年,前端发展呈百家争鸣式发展,框架层出不穷,版本更是迭代不穷,难免会出现前端项目技术栈不统一、所用框架版本不统一。比如,有的项目中,还采用了angelar1.0、vue1.0等。而这些项目若没有新的功能加入,线上稳定运行,对其重构成本会很高。但却需要结合到新的应用中去,遇到的较多的情况是:旧的应用使用的是 Angular.js 编写,而新的应用开始采用 Angular 2+。这对于业务稳定的团队来说,是极为常见的技术栈。在即不重写原有系统的基础之下,又可以抽出人力来开发新的业务。其不仅仅对于业务人员来说, 是一个相当吸引力的特性;对于技术人员来说,不重写旧的业务,同时还能做一些技术上的挑战,也是一件相当有挑战的事情。
而前端微服务的一个卖点也在这里,去兼容不同类型的前端框架。除此之外,在这两三年里,移动应用出现了一种趋势,用户不想装那么多应用了。而往往一家大的商业公司,会提供一系列的应用。这些应用也从某种程度上,反应了这家公司的组织架构。然而,在用户的眼里他们就是一家公司,他们就只应该有一个产品。相似的,这种趋势也在桌面 Web 出现。聚合成为了一个技术趋势,体现在前端的聚合就是微服务化架构。
实现方案
理想的前端微服务化,应该是符合下面几个特点:
- 独立部署
- 独立开发
- 技术无关
- 不影响用户体验
其实现方式:
- 使用 HTTP 服务器的路由来重定向多个应用,即路由分发
- 在不同的框架之上设计通讯、加载机制,诸如Single-SPA 和 Mooa
- 通过组合多个独立应用、组件来构建一个单体应用
- iFrame。使用 iFrame 及自定义消息传递机制
- 使用纯 Web Components 构建应用
路由分发
路由分发式微前端,即通过路由将不同的业务分发到不同的、独立前端应用上。其通常可以通过 HTTP 服务器的反向代理来实现,又或者是应用框架自带的路由来解决。
就当前而言,通过路由分发式的微前端架构应该是采用最多、最易采用的 “微前端” 方案。但是这种方式看上去更像是多个前端应用的聚合,即我们只是将这些不同的前端应用拼凑到一起,使他们看起来像是一个完整的整体。但是它们并不是,每次用户从 A 应用到 B 应用的时候,往往需要刷新一下页面。通常可通过nginx配置反向代理,来进行路由分发,从而实现前端微服务
它适用于以下场景:
- 不同技术栈之间差异比较大,难以兼容、迁移、改造
- 项目不想花费大量的时间在这个系统的改造上
- 现有的系统在未来将会被取代
- 系统功能已经很完善,基本不会有新需求
- 应用切换时,刷新整个页面
而在满足上面场景的情况下,如果为了更好的用户体验,还可以采用 iframe 的方式来解决。
使用 iFrame 创建容器
iframe 可以创建一个全新的独立的宿主环境,这意味着我们的前端应用之间可以相互独立运行。采用 iframe 有几个重要的前提:
- 网站不需要 SEO 支持
- 需要设置加载机制
- 需要设置通讯机制
即何时加载、卸载应用,如何监听应用事件等。
框架之上设计通讯、加载机制
不论是基于 Web Components 的 Angular,或者是 VirtualDOM 的 React 等,现有的前端框架都离不开基本的 HTML 元素 DOM。
那么,我们只需要:
- 在页面合适的地方引入或者创建 DOM
- 用户操作时,加载对应的应用(触发应用的启动),并能卸载应用。
第一个问题,创建 DOM 是一个容易解决的问题。而第二个问题,则一点儿不容易,特别是移除 DOM 和相应应用的监听。当我们拥有一个不同的技术栈时,我们就需要有针对性设计出一套这样的逻辑。现有的框架有single-spa、qiankun、mooa等
通过组合多个独立应用、组件来构建一个单体应用
常见的方式有:
- 独立构建组件和应用,生成 chunk 文件,构建后再归类生成的 chunk 文件。(这种方式更类似于微服务,但是成本更高)
- 开发时独立开发组件或应用,集成时合并组件和应用,最后生成单体的应用。
- 在运行时,加载应用的 Runtime,随后加载对应的应用代码和模板。
但是,首先它有一个严重的限制:必须使用同一个框架。
其次,采用这种方式还有一个限制,那就是:规范!**规范!**规范!。在采用这种方案时,我们需要:
- 统一依赖。统一这些依赖的版本,引入新的依赖时都需要一一加入。
- 规范应用的组件及路由。避免不同的应用之间,因为这些组件名称发生冲突。
- 构建复杂。在有些方案里,我们需要修改构建系统,有些方案里则需要复杂的架构脚本。
- 共享通用代码。这显然是一个要经常面对的问题。
- 制定代码规范。
纯 Web Components 技术构建
Web Components 组件可以拥有自己独立的 Scripts
和 Styles
,以及对应的用于单独部署组件的域名。然而它并没有想象中的那么美好,要直接使用纯 Web Components 来构建前端应用的难度有:
- 重写现有的前端应用。是的,现在我们需要完成使用 Web Components 来完成整个系统的功能。
- 上下游生态系统不完善。缺乏相应的一些第三方控件支持,这也是为什么 jQuery 相当流行的原因。
- 系统架构复杂。当应用被拆分为一个又一个的组件时,组件间的通讯就成了一个特别大的麻烦。
- 浏览器兼容问题
现有框架
现有的微前端框架有single-spa、qiankun、mooa。其均是在前端框架之上设计通讯、加载机制来实现的。
其中single-spa已经实现了大部分框架(vue、react、angular)的启动和卸载处理,但不适用于生产环境
qiankun是基于spa-single实现的以运行在生产环境为目标的微前端服务框架
Mooa是一个仅仅基于angular框架的微前端框架
截止到20191102,其star数如下
- single-spa https://github.com/CanopyTax/single-spa 4132stars
- qiankun https://github.com/umijs/qiankun 1700stars
- mooa https://github.com/phodal/mooa 482stars
其具体使用,可参考官方文档