前端架构发展史

1,739 阅读8分钟

前端改革 30 年,从一片荒芜到微前端兴起。

前言

原文链接: 前端架构发展史

本文主要简述前端系统级架构的演讲历史,不涉及应用级架构: MVC,MVMM...

正文

前置术语

  • 应用:指的是一个整体的应用,可由多个模块组成。
  • 模块:指的是整体应用下 被划分的子应用。

无架构

在 1990 年,Tim Berners-Lee 在他的 NeXT 电脑上部署了第一套“主机-网站-浏览器”构成的 Web 系统,这标志着前端的开始。

在最初,前端是一片荒芜的,经过浏览器大战,W3C 标准化的过程 前端才慢慢成长了起来。

在此时期,诞生了 CSS、JavaScript、DHTML 等重要技术。前端也从最开始的纯静态页面,逐步存在于 PHP、ASP、JSP 这些模板技术中。

由于前端涉及到的功能简单,只需操作 DOM,并不需要代码管理与模块支持。

所以 最初的前端只是 MVC 架构中的 View,如下面的模板,没有架构可言。

<html>
  <head><title>Car {{ $car->id }}</title></head>
  <body>
    <h1>Car {{ $car->id }}</h1>
    <ul>
      <li>Make: {{ $car->make }}</li>
      <li>Model: {{ $car->model }}</li>
      <li>Produced on: {{ $car->produced_on }}</li>
    </ul>
  </body>
</html>

前后端分离架构

在 1999 年,IE 浏览器支持了 XMLHttpRequest 接口,允许 JavaScript 异步发出 HTTP 请求,这为以后的前端发展 埋下了重要伏笔。

2005 年,在 Google 广泛应用 Ajax 通信 获得一系列产品成功后,这种不需要刷新页面就可以与服务器通信的技术 开始被开发者所重视。

但 Ajax 带来的不仅是一种可异步通信的技术,而是开发模式上的解耦。

前端不再是后端的模板,前端也可以实时地获取数据,动态地渲染内容。

在此时期,前端逐步从纯内容展示的静态网页 向 具备数据交互的动态网页转变,前端开发变得复杂起来。

与此同时,互联网带来的商业价值 推动了其他技术的产生,这其中就包括了 大名鼎鼎的 V8 。

在 V8 开源的第二年,Nodejs 出现了,让 JS 可以 run everywhere。

也正是因为它把前端快速带进了刀耕火种时代,其中最受益的就是工程化的兴起。

  • 构建工具:gulp webpack
  • 包管理:npm yarn
  • 排名第一的包生态

除此之外,标准化组织 W3C 也在 08 年发布 HTML5 正式草案。

随着资本的重视,工程化的兴起,开源社区的努力,开发模式的创新,整个前端开发 开始呈现野蛮增长现象。

从 2010 年 10 月出现的 Backbone 开始,Knockout、Anjular、Ember、Meteor、Vue 相继出现,前端开发颇有一副 不管 MVC 、MVVM 还是 全栈开发,我全都要的气势。

在此期间,有一股潮流慢慢被大家所认可,就是单页面应用。

但单页面应用代表的不只是工程技术化的产物,而重要的是一种网页 应用化的思想。

而随着单页面应用的流行,移动端的兴起,前后端分离的架构也成为了行业的标准实践。

由此,前端不再是后端 MVC 中的 V,而是单独的一层。

前端开始进入前后端分离时代。

微前端架构

微前端的概念由ThoughtWorks于2016年的一期技术雷达提出,

摘自技术雷达:

我们已经从引入微服务架构中获得了明显的好处,微服务架构可以让团队裁剪出独立部署的交付物以及可维护的服务。不幸的是,我们还看到许多团队在后端服务之上创建了前端单体——一个单一,庞大和杂乱无绪的浏览器应用。我们首选的(经过验证的)方法是将基于浏览器的代码拆分成微前端。在这种方法中,Web 应用程序被分解为多个特性,每个特性都由不同的前后端团队拥有。这确保每个特性都独立于其他特性开发,测试和部署。这样可以使用多种技术来重新组合特性——有时候是页面,有时候是组件——最终整合成一个内聚的用户体验。

“微”是一个很神奇的概念,底层的微内核设计,大行其道的微服务概念,以及本章的微前端主题。

微 实质上代表的概念是模块化,而模块化具有的思想是: 单一职责、关注分离,分而治之,这些思想 在软件工程中体可谓是金玉良言。

在我看来 微前端的出现 是一种趋势,是 WEB2.0 时代应用复杂性的一种体现,也标志着前端从刀耕火种的时代跨入了工业化时代。

在一些小型应用中,往往几个 单页面就足以支撑起整个应用。

而在一些中大型的应用中,业务的复杂性、工程的庞大性 都难以控制,如果继续使用传统的开发模式,不仅应用的状态难以管理,打包出来的应用难以优化,就连协作开发都存在很大的耦合性。

微前端 使用去中心化的思想可以有效分解大型应用的复杂度,将大型应用划分成一个个独立的模块,根据功能、业务场景来进行自由编排,这些模块通过统一的入口注册组合,通过约定的方式来进行通信,各个模块可以做到并行开发,独立部署,而且技术栈也随之解耦。

Application

但是微前端并不是提升研发效率的银弹,需要根据具体场景来衡量是否使用,而架构就是权衡的艺术,微前端为我们提供了一种系统级的维度。

使用场景

适合场景

  1. 聚合型的应用

    这种应用主要存在 业务场景多样且业务之间依赖性很低的场景。

    就比如 Top 运营系统,每一个模块都可以单独抽成一个应用进行开发 且 满足单一职责原则,替换掉某一模块时也不会影响全局应用。

  2. 逻辑重复型的应用

    这种应用的特征是,子模块之间存在很多共同的业务逻辑,重复建设严重。

    就比如 电商系统,在 PC端,H5终端 都会有商品推荐,购买商品这些基本的功能,属于业务逻辑基本相同,UI 相差较大。

    微前端可以将子模块之间相同的业务逻辑 提取到主应用,然后各个子模块通过约定的方式进行通信,这样子模块的维护性会得到提升。

  3. 需保留老模块的应用

    在现代的前端开发时,由于技术栈日新月异,如何处理遗留模块 是一个无论绕过的问题。

    如果旧模块可以继续使用,并且重写需要花很多时间力气的话,那么使用微前端 整合进现有应用是一个很好的方案。

  4. 需数据隔离的应用

    数据隔离指的是 状态隔离,样式隔离。

    如果一个应用的单个页面存在多种模块时,数据冲突 不能忽视,比如模块中的全局变量,事件,通用样式 很可能造成问题。

    这种问题通常需要"沙箱化"来解决,而微前端提供了很好的实践。

    "沙箱化"还能提供应用的容错性,当一个子模块出现错误时,不会影响到全局应用,真正做到弹性应用。

  5. 技术栈灵活的应用

    使用微前端在系统级层面进行模块地抽象组合,磨平了不同技术栈带来的差异,做到模块之间技术栈的隔离。

    在同一应用下 每个团队可以根据自身需求,选择最合适自己的技术栈。

  6. 需要敏捷化开发的应用

    因为微服务提供了 模块级的组件化架构,完全可以做到多个模块之间并行开发,独立部署,无论模块的需求如何增长,都不会影响到全局应用。

    并且天然的增量构建,有利于持续部署。在团队协作开发层面也是一种很好的实践。

  7. 无法可持续迭代的应用

    这种应用一般都是巨石型应用,存在的问题很明显: 随着业务需求的迭代,代码量级越来越大,开发效率越来越低,新业务的接入成本随之变高。

    这种场景只能从技术维度来进行切入,需将巨石应用划分模块来处理臃肿。

不适合场景

  1. 应用之间存在很强的业务依赖 或者 拆分的粒度很难掌握,如果强行使用微前端规范,很可能起到相反的作用。
  2. 小型应用,没必要过度设计。
  3. 对性能有要求的应用,微前端因为多加了一层抽象,如果不是从工程化进行模块组合的话,极有可能为页面增加很多无意义的网络请求,内存消耗,影响最终的用户体验。
  4. 基础设施较弱的应用。

结束语

下篇文章将讲述微前端的实践原理,敬请关注。

转载本文请注明作者和出处 一个坏掉的番茄,请勿用于任何商业用途。