微前端架构初探以及个人前端技术盘点

前言

最近几年微前端一直是前端界的热门议题, 它相似于微服务架构, 主要面向于浏览器端,能将一个复杂而庞大的单体应用拆分为多个功能模块清晰且独立的子应用,且共同服于务同一个主应用。各个子应用能够独立运行、独立开发和独立部署。javascript

微前端架构概念的诞生及应用对于提供复杂应用服务的企业来讲显然是一种机遇, 一样也是一种挑战.本文主要就微前端架构的概念和实现方案作一个总结和复盘,而且经过一个实际案例来实践微前端架构,但愿能对一样有此需求的朋友们提供一些帮助和思路.css

你将收获

  • 什么是微服务以及微服务能给企业带来什么
  • 微前端架构概念及方案
  • umi下的微前端架构方案实战
  • 一个程序员的技术复盘与展望

正文

在总结微前端架构以前,让咱们来先看看微服务是什么.html

1.什么是微服务以及微服务能给企业带来什么

微服务是一种用于构建应用的架构方案。微服务架构有别于更为传统的单体式方案,可将应用拆分红多个核心功能。每一个功能都被称为一项服务,能够单独构建和部署,这意味着各项服务在工做(和出现故障)时不会相互影响。前端

传统的web软件开发架构每每以下图所示: vue

虽然咱们在传统应用中能够采用 模块化来拆分业务逻辑和开发方式,但最终它们会打包并部署为单体式应用。这种架构每每更适合中小型项目, 开发简单直接,更适合集中化管理应用.但每每也会存在不少缺点,好比可扩展性不足,相同或者类似业务复用困难,部署时间长, 业务复杂以后很难维护等问题.

对于复杂系统和业务来讲,咱们通常会采用微服务架构。其思路是将一个完整的应用分解为小的、互相链接的微服务,每一个服务完成特定的功能, 而且某些特定的服务还能为其余服务提供API接口. java

由上图能够发现微服务给咱们带来的好处:

  • 将一个庞大的单体拆解成多个子服务,大大下降了开发复杂度
  • 任务边界划分明确, 每一个子服务之间单独开发, 不一样服务之间可并行由不一样的开发人员开发,提升开发效率
  • 更细粒度的增强了模块化进程, 可维护性和可读性更高
  • 团队之间只要制定好API约定, 那么不一样成员或者团队能够采用不一样的技术开发服务
  • 可用共享服务, 使得不一样子服务可组合实现更复杂的功能
  • 每一个微服务可独立部署发布,使得自动化CI(持续集成)/CD(持续交付)成为可能

但微服务并非任何场景下都是合适的, 微服务的目标是充分分解应用程序,以促进敏捷开发和持续集成部署。在部署微服务时咱们须要作好适当的边界划分,并处理不一样微服务之间的并发问题,这些都是对整个项目带来的挑战,须要更加专业的技术成员来把控.目前市面上也有不少开源的微服务框架好比Dubbo, Spring Cloud等,笔者以前公司采用的Spring Cloud就是一个很好的微服务架构方案.node

2.微前端架构概念及方案

2.1 理解微前端架构

上面简单介绍了一下微服务架构,接下来咱们进入主题,来聊聊微前端. 微前端微服务实现的目的相似,都是将应用由单一的单体应用转变为多个小型子应用,差异就在于:react

  1. 微前端应用于浏览器端,主要是对web应用进行拆解,最后将不一样子系统(模块)聚合成一个完整的应用.
  2. 微前端主要目的是聚合,即将不一样子系统聚合成一个大系统,而微服务架构目前更可能是解耦,即解耦不一样服务间的依赖.

咱们先来看看微前端的一些思考者. jquery

Michael Geers 大佬发表了一些对微前端的一些思考,内容大体总结一下就是:

“ 微前端 ”是将微服务的概念扩展到前端领域。为了构建一个功能强大的浏览器应用程序(也称为单页应用程序),当前广泛的趋势是将其创建在微服务架构之上。可是随着时间的流逝,一般由独立团队开发的前端层会不断增加,而且变得更加难以维护。Micro Frontends背后的想法是将Web应用程序视为由独立团队拥有的功能的组合。每一个团队都有本身关心和专长的不一样业务或任务领域。每一个团队能够跨职能,而且从数据库到用户界面,端到端地开发其功能。webpack

正以下面的例子所示:

当咱们的系统中有多个不一样的子模块,而且子模块之间有相对独立且完整的功能体系时, 一旦子模块变得愈来愈多, 那么整个应用将变得很是庞大且臃肿,开发和维护成本大大提升.若是在这种场景下咱们采用SPA模式开发,那么项目后期将变得不可想象,页面首次加载将变得很是慢(笔者曾经就经历过,开发一个复杂系统页面首次加载花了20多秒,因此不得不采用MPA来处理); 可是咱们采用MPA(多页应用)模式,虽然解决了应用臃肿的问题, 但仍然存在不少有待处理问题,好比模块切换须要从新刷新页面, 公共组件没法共享,子模块直接,父子模块之间的通讯问题,开发部署繁琐等.这写都是传统开发模式会遇到的问题.

试想一下,若是面对以上问题, 若是有一种架构模式, 可让咱们在主应用中共享公共组件和状态(可是要保证子应用运行时内部的状态隔离), 而且不一样子模块之间能够单独开发部署, 模块间切换不刷新页面, 而且模块之间,父子应用之间能够经过某种简单的方式实现通讯,这样是否是就完美了?不错, 这也许就是微前端要解决的问题.

每每企业的中后台系统更加适合使用微前端架构,由于B端大部分都是业务驱动,而每每这些业务之间会很是复杂, 好比Saas, Paas等系统.像相似于云平台,CRM,ERP系统每每是微前端架构的拯救对象.

笔者曾经接手的ERP系统,因为开发时间比较早,每每有不少遗留的历史包袱,好比新老技术栈的糅合, 前端业务代码庞大而毫无违和感,为了对其继续迭代开发, 重构是必经之路,微前端另外一个重要的做用笔者认为就是解放.解放不可挽回的痛😭.

笔者以前在写从0到1教你搭建前端团队的组件系统(高级进阶必备)这篇文章时简单提了一下微前端的一些知识,这里先回放一张笔者以前作的简陋的图,方便你们理解微前端架构.

但咱们所看到的不是事实的所有,在文章后面笔者会总结一张更全面的图,来整理微前端的一些实践应用.

2.2 微前端架构实现的方案

上面内容咱们大体了解了一下微前端的概念和做用,接下来笔者总结一下曾经经历过的微前端实现方案.

1. 基于MPA + iframe + requirejs实现的微前端架构 这是笔者接手最先的一个项目,主要是服务于企业内部的ERP系统,当时采用的技术栈主要是jquery+layui+requirejs,记得仍是笔者刚毕业时参与的项目.主要是利用AMD模块化机制来复用代码,当时项目代码及其庞大复杂,大体架构以下:

传统实现方式通常是通多多页面的方式来对应用解耦,并采用模块化加载机制来导入可复用组件.系统间通型采用storage+window.opener+iframe.好比咱们一个大系统的首页可能会有来自不一样子系统的页面,已iframe的方式嵌入.不一样子系统间由不一样的人维护,虽然作到了微前端的模式,可是仍是有不少缺点.
改架构的通常分工是架构组主要负责制定架构标准和规范,维护公共模块(相似于如今的组件,当时因为采用jquery生态,能够简单的说成公共UI插件的维护);业务组主要负责编写业务代码,实现某个系统的具体交互和功能。

2. 基于MPA + iframe + Webpack实现的微前端架构 基于MPA + iframe + Webpack实现的微前端架构实现和上面介绍的传统架构实现相似,只不过采用了更新的技术栈,以及真正的模块化,组件化技术。笔者以前作的Saas系统就是一个很典型的该方案的例子:

上图可知不一样子系统之间能够各自维护,单独打包部署,最后经过node或者nginx作路由分发。咱们采用公共的ui组件库和js类库来抽离公共组件,可是前提是不一样组件库和技术栈强相关,若是没有历史遗留的新项目,建议采用一致的技术栈。

以上两个方案的缺点就是组件库只能复用而没法真正共享,而且切换路由会致使页面从新渲染刷新。父子系统通讯困难,仍然须要iframe最为容器来通讯。(有关iframe父子页面通讯的各类方式笔者在记一次老项目中的跨页面通讯问题和前端实现文件下载功能

3. 基umi + qiankun实现的微前端架构 目前市面上也有很是成熟的微前端架构方案,好比single-spa,以前的美团外卖微前端架构和蚂蚁金服基于single-spa开发的微前端架构qiankun(乾坤),都是很是不错的方案。

qiankun主要采用HTML Entry模式,直接将子应用打出来 HTML做为入口,主框架能够经过 fetch html 的方式获取子应用的静态资源,同时将 HTML document 做为子节点塞到主框架的容器中。这样不只能够极大的减小主应用的接入成本,子应用的开发方式及打包方式基本上也不须要调整,并且能够自然的解决子应用之间样式隔离的问题。

其方案具备以下特色:

  • 支持子应用并行
  • 支持js沙箱环境(js隔离)
  • css隔离
  • HTML Entry,简化开发者使用
  • 按需加载
  • 公共依赖加载
  • 父子应用通讯机制
  • 子应用嵌套

由于咱们的前端项目基于umi生态开发构建(以前采用webpack搭建,后面发现umi使用也很爽,就直接基于umi二次开发了),因此很天然的选择了乾坤做为微前端架构。具体架构以下:

3.umi下的微前端架构方案实战

接下来我具体介绍如何使用乾坤来搭建咱们的微前端架构,因为咱们内部采用umi,因此这里咱们直接使用其提供的@umijs/plugin-qiankun插件来实现。(好处就是改动成本几乎为零) 首先咱们来实现这样一个场景:咱们有一个主应用做为基座工程,而后有3个子系统,他们是独立建立维护的,能够采用不一样的git仓库来管理。当咱们在主应用中切换路由时会切换到对应的子系统,且不刷新页面,彻底的SPA体验,接下来咱们来具体实现一下吧。

这里咱们采用umi2.0来开发,关于如何安装与使用umi,这里就不作详细介绍了。

  1. 建立工程
mkdir mainSystem subSystemA subSystemB subSystemC
// 分别进入各系统目录下,执行如下命令建立咱们的项目
yarn create umi
复制代码
  1. 在各个系统下安装@umijs/plugin-qiankun插件
yarn add @umijs/plugin-qiankun
复制代码
  1. 主应用下的配置
// .umirc.js
export default {
  plugins: [
    [
      '@umijs/plugin-qiankun',
      {
        master: {
          // 注册子应用信息
          jsSandbox: true, // 是否启用 js 沙箱,默认为 false
          prefetch: true, // 是否启用 prefetch 特性,默认为 true
        },
      },
    ],
  ],
};
// app.js
const isDev = process.env.NODE_ENV === 'development'
export const qiankun = {
  apps: [
    {
      mountElementId: 'root-subapp-container',  // 洗子应用挂载的节点
      name: 'subSystemA', // 惟一 id,和package对应的name字段最好保持一致
      entry: isDev ? '//localhost:8001' : '/subSystemA/index.html', // html entry
      base: '/subSystemA',  的路由前缀,经过这个前缀判断是否要启动该应用,一般跟子应用的 base 保持一致
      history: 'browser', // 子应用的 history 配置,默认为当前主应用 history 配置
    },
    {
      mountElementId: 'root-subapp-container',
      name: 'subSystemB',
      entry: isDev ? '//localhost:8002' : '/subSystemB/index.html',
      base: '/subSystemB',
    },
    {
      mountElementId: 'root-subapp-container',
      name: 'subSystemC',
      entry: isDev ? '//localhost:8003' : '/subSystemB/index.html',
      base: '/subSystemC',
    }
  ],
  fetch: url => {
    return fetch(url)
  }
};
复制代码

以上是基本的配置,固然咱们还能够在app.js里面加入lifeCycles等钩子来控制不一样生命周期下的行为。

在子应用中咱们一样须要引入@umijs/plugin-qiankun这个插件,具体配置以下:

export default {
  base: `/${appName}`, // 子应用的 base,默认为 package.json 中的 name 字段
  plugins: ['@umijs/plugin-qiankun', { slave: true }],
};
复制代码

基本准备工做已经完成,剩下就是编写业务代码了,咱们要想让整个应用一块儿跑起来,须要先启动基座工程,而后再启动对应的子工程(固然他们能够单独运行)。

可是值得注意的是咱们在开发环境中采用devServer提供的带来才能跨域抓取资源,若是应用发布到线上,若是不一样子应用采用不一样域名,咱们还须要解决跨域问题(跨域解决的方案及安全机制也有不少,已经再也不是个问题)。实际开发环境咱们须要考虑的问题还有不少,这里只作简单介绍,不过根据官方提供的api基本上能够知足大部分的需求场景,因此仍是很是值得一试的。笔者后期也会写一个微前端的实际案例发布到github上,能够一块儿交流学习。

4.一个程序员的技术复盘与展望

因为今年受疫情影响,工做任务比较紧张,复盘的时间也比较少,可是笔者仍是会坚持每周更新1-2篇文章,来总结和复盘工做中或学到的新技术。本身写的零零散散的文章是时候作一个分类和梳理,以便更加清晰将来的方向和不足的补救。

1.node相关

2.工程化相关

3. 设计模式

4.react相关

5.vue/angular相关

6.css相关

7.算法相关

8. H5游戏

9.原生javascript类库设计封装

10.工做问题汇总

最后

若是想学习更多H5游戏, webpacknodegulpcss3javascriptnodeJScanvas数据可视化等前端知识和实战,欢迎在公号《趣谈前端》加入咱们的技术群一块儿学习讨论,共同探索前端的边界。

相关文章
相关标签/搜索