前端微服务设计

673 阅读6分钟

为什么需要微服务

同一个项目的技术栈不需要统一,可以兼容不同类型的前端框架

近些年,前端发展呈百家争鸣式发展,框架层出不穷,版本更是迭代不穷,难免会出现前端项目技术栈不统一、所用框架版本不统一的情况。 如若某些项目,没有新的功能加入,又能线上稳定运行,但其技术栈却用的是 vue1.0,为了将其结合到新应用中去而对其重构,成本会很高。然而,微服务可以帮我们解决这个问题。 在既不重写原有系统的基础之下,又可以抽出人力来开发新的业务。其不仅仅对于业务人员来说是一个相当吸引力的特性,对于技术人员来说,不重写旧的业务,能在一些新技术上做挑战,也是一件很有意思的事情。 除此之外,在这两三年里,移动应用出现了一种趋势,用户不想装那么多应用。而往往一家大的商业公司,会提供一系列的应用。这些应用也从某种程度上,反应了这家公司的组织架构。然而,在用户的眼里他们就是一家公司,他们就只应该有一个产品。相似的,这种趋势也在桌面 Web 出现。聚合成为了一个技术趋势,体现在前端的聚合就是微服务化架构。

微服务实现的条件

理想的前端微服务化,应该是符合如下几个特点:

  • 能够独立部署
  • 能够独立开发
  • 无所谓技术栈
  • 不影响用户的整体体验

实现方式

  1. 使用 HTTP 服务器的路由来重定向多个应用,即路由分发

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

  3. 通过组合多个独立应用、组件来构建一个单体应用

  4. 在不同的框架之上设计通讯、加载机制,诸如 Single-SPA 和 Mooa

  5. 使用纯 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框架的微前端框架