前端改革 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 时代应用复杂性的一种体现,也标志着前端从刀耕火种的时代跨入了工业化时代。
在一些小型应用中,往往几个 单页面就足以支撑起整个应用。
而在一些中大型的应用中,业务的复杂性、工程的庞大性 都难以控制,如果继续使用传统的开发模式,不仅应用的状态难以管理,打包出来的应用难以优化,就连协作开发都存在很大的耦合性。
微前端 使用去中心化的思想可以有效分解大型应用的复杂度,将大型应用划分成一个个独立的模块,根据功能、业务场景来进行自由编排,这些模块通过统一的入口注册组合,通过约定的方式来进行通信,各个模块可以做到并行开发,独立部署,而且技术栈也随之解耦。
但是微前端并不是提升研发效率的银弹,需要根据具体场景来衡量是否使用,而架构就是权衡的艺术,微前端为我们提供了一种系统级的维度。
使用场景
适合场景
-
聚合型的应用
这种应用主要存在 业务场景多样且业务之间依赖性很低的场景。
就比如 Top 运营系统,每一个模块都可以单独抽成一个应用进行开发 且 满足单一职责原则,替换掉某一模块时也不会影响全局应用。
-
逻辑重复型的应用
这种应用的特征是,子模块之间存在很多共同的业务逻辑,重复建设严重。
就比如 电商系统,在 PC端,H5终端 都会有商品推荐,购买商品这些基本的功能,属于业务逻辑基本相同,UI 相差较大。
微前端可以将子模块之间相同的业务逻辑 提取到主应用,然后各个子模块通过约定的方式进行通信,这样子模块的维护性会得到提升。
-
需保留老模块的应用
在现代的前端开发时,由于技术栈日新月异,如何处理遗留模块 是一个无论绕过的问题。
如果旧模块可以继续使用,并且重写需要花很多时间力气的话,那么使用微前端 整合进现有应用是一个很好的方案。
-
需数据隔离的应用
数据隔离指的是 状态隔离,样式隔离。
如果一个应用的单个页面存在多种模块时,数据冲突 不能忽视,比如模块中的全局变量,事件,通用样式 很可能造成问题。
这种问题通常需要"沙箱化"来解决,而微前端提供了很好的实践。
"沙箱化"还能提供应用的容错性,当一个子模块出现错误时,不会影响到全局应用,真正做到弹性应用。
-
技术栈灵活的应用
使用微前端在系统级层面进行模块地抽象组合,磨平了不同技术栈带来的差异,做到模块之间技术栈的隔离。
在同一应用下 每个团队可以根据自身需求,选择最合适自己的技术栈。
-
需要敏捷化开发的应用
因为微服务提供了 模块级的组件化架构,完全可以做到多个模块之间并行开发,独立部署,无论模块的需求如何增长,都不会影响到全局应用。
并且天然的增量构建,有利于持续部署。在团队协作开发层面也是一种很好的实践。
-
无法可持续迭代的应用
这种应用一般都是巨石型应用,存在的问题很明显: 随着业务需求的迭代,代码量级越来越大,开发效率越来越低,新业务的接入成本随之变高。
这种场景只能从技术维度来进行切入,需将巨石应用划分模块来处理臃肿。
不适合场景
- 应用之间存在很强的业务依赖 或者 拆分的粒度很难掌握,如果强行使用微前端规范,很可能起到相反的作用。
- 小型应用,没必要过度设计。
- 对性能有要求的应用,微前端因为多加了一层抽象,如果不是从工程化进行模块组合的话,极有可能为页面增加很多无意义的网络请求,内存消耗,影响最终的用户体验。
- 基础设施较弱的应用。
结束语
下篇文章将讲述微前端的实践原理,敬请关注。
转载本文请注明作者和出处 一个坏掉的番茄,请勿用于任何商业用途。