速来报名!AICon北京站鸿蒙专场~ 了解详情
写点什么

深度解读当代前端架构演进与趋势(上)

  • 2019-09-26
  • 本文字数:9305 字

    阅读完需:约 31 分钟

深度解读当代前端架构演进与趋势(上)

软件架构的核心思想,就是推断软件系统各个组件之间数据流动的方式。软件架构的质量取决于你设法推断这些数据流的难易程度!本文要讲的内容,就是在今天的 Web 应用程序背后探索这些数据流和最终的体系结构。Web 应用已从简单的静态网站(双层结构)发展为复杂的多层次、SPA 和 SSR 驱动的 API 优先系统。CMS 系统已发展成无头(Headless)和内容优先的系统。


近年来,前端社区的面貌日新月异。早年流行的是 jQuery 引入的 DOM 注入算法,其很快被基于 MVC 的 Backbone.js 所取代。之后一夜之间,我们就身陷于双向和单向数据流架构的丛林之中。我们的成长足迹在某处中断了。曾几何时沉浸在 MVC 的世界是如何突然进入 React 开创的单向数据流时代的?它们之间有什么联系?随着本文展开,我们将尝试解开这个难题。


虽然本文针对的是前端工程师,但想要从宏观层面理解现代 Web 应用程序架构的 Web 开发人员都能从本文中获益。软件体系背后有着大量活动——流程、需求收集、部署拓扑、技术栈等等。但那些已经超出了本文所涉及的范围。

必要的前置知识——什么是计算机?

计算机是一种从用户收集数据/信息,并立刻或稍后将处理过的数据/信息提供给用户的机器。计算机如何收集和展示这些数据呢?它使用软件应用来实现这一目的。


软件架构的关键是提供合理的手段来组成软件,同时保持一切井然有序。


这里的关键在于,软件应用正在处理的数据被称为模型应用程序状态。一些勇士可能将其称为应用程序的域模型业务逻辑。应用程序可以是桌面端也可以是 Web 端。


本文的宗旨是探索向(Web 前端的)用户表示这种应用程序状态的合理方式,同时让一切井然有序。我们将探索数据如何从模型流向视图层,仅此而已。

经典 MVC——起源

将数据与表示分离是(Web 端和桌面端)图形用户界面的核心思想。对于 MVC——模型-视图-控制器来说,将表示(视图)与关注域(模型)分离是其主导的设计理念。毫无疑问,MVC 是一项开创性的成果,其影响力绵远流长。


如果要为软件开发写出第一原则,那么它就会是 SoC——关注点分离。而且 MVC 模式可能是它第一个真正的落地实践。


MVC 是为 Smalltalk-80 语言推出的。在 MVC 中,视图(View)对象显示模型(Model)对象持有的数据。在我们全面研究 MVC 中的数据流之前,我们必须了解当时(约 20 世纪 70 年代)的软件应用环境:


  • 这个 MVC 仅适用于桌面应用。那时离 Web 诞生还有几十年的时间。

  • 没有 Web,复杂的 GUI 驱动的操作系统也不存在。

  • 这意味着应用软件非常接近底层硬件。


以上这些限制对 MVC 影响很大。于是需要由控制器(Controller)对象负责响应键盘或鼠标等用户输入并转换为模型上的操作。此外,操作系统缺少 GUI 小部件意味着视图与屏幕内容无法对应。


相反,视图和控制器以配对的形式结合在一起。其中视图部分向用户显示输出内容,控制器部分接收来自用户的输入。应该注意的是,屏幕上的每个控件都有一个视图——控制器配对,这也是小部件(widget)理念的雏形。


今天,在 React、Vue 或 Angular 中,这种视图——控制器配对与组件的思想是一样的,尽管状态处理层面的具体机制有所不同。


关于 MVC 就介绍到这里,下面的图片展示了 MVC 中的数据流示例。在这个例子中,我们有一个带递增和递减按钮的简单计数器。计数器状态维持着模型。此外,我们把两个按钮简化成了一个来简化叙述。



经典 MVC


在协作方面:


  1. 视图控制器包含对模型的直接引用,但反过来不行。这意味着模型不依赖 UI,可以在不担心 UI 问题的前提下做更改。

  2. 模型实现了观察者(Observer)模式,被一个或多个视图对象注册(subscribe)。当模型更改时会触发事件,事件响应后视图也会更新。


MVC 中有两条数据流。在视图流中不涉及模型,只涉及 UI 的更改。显示按钮单击效果或对鼠标滚动事件作出响应就是视图流的例子。



MVC 中的数据周期


今天我们不再使用这个 MVC 了,它有时被称为经典 MVC 老爹的 MVC

开始使用应用程序模型

人们很快就意识到应用程序状态无法与 GUI 完全隔离。我们总是要维护某种表示逻辑视图状态


复杂的图形界面需要额外的状态,这些状态只用来辅助 UI 小部件,实现更好的用户体验。


但这可能会导致一些问题。来看看之前的计数器示例。当计数器达到 10 时,我们必须将标签的颜色从黑色更改为红色以表示警告。这种颜色变化行为实际上不是业务逻辑或关注点。这是纯粹的美学部分(用户体验),需要加进来。真正的问题是——放在哪里?是模型还是视图


由于这种表示逻辑视图状态基本上是从域模型派生的状态,因此必须在模型对象中维护它。但是域模型又要维护视觉部分(比如说红色),这种定义就很尴尬。如果我们将它放在视图对象中,那么它会引入另一组问题。我们的标签小部件不再是通用的了,无法在其他地方复用。此外,在视图对象中放一个带有硬编码数字 10 的条件,意味着我们正在泄漏某些业务逻辑。


为了解决这个问题,我们在原始的 MVC 中添加了另一个实体——应用程序模型(Application Model,AM)。有了 AM 以后,视图——控制器配对不再直接访问模型了。相反,它们向 AM 事件注册并使用它来访问所需的数据。



应用程序模型 MVC


数据流和经典 MVC 是一样的。当然,每种模式都有其优点和缺点,AM-MVC 也不例外。最突出的问题是 AM 没有对视图对象的直接引用,因此即使 AM 被设计为维持视图状态,也无法直接操作后者。


总的来说,引入应用程序模型会使视图特定的状态远离域层,并降低了视图对象的复杂性来简化视图对象。这和表示模型(Presentation Model)很像,这是 Martin Fowler 在其开创性研究中创造的概念:


表示模型的本质是一个完全自包含的类,它表示 UI 窗口的所有数据和行为,但没有任何用于在屏幕上渲染该 UI 的控件。视图只是将表示模型的状态显示在屏幕上。

现代桌面架构的时代

时光飞逝,世界也在不断变化,新一代操作系统开始展现威力。应用程序远离了底层硬件,它们之间加入了完整的内核、OS 驱动程序和实用程序。像 Windows 这样基于 GUI 的操作系统提供了开箱即用的 UI 小部件。


不再需要控制器来监听输入设备了。视图对象的理念改变了。


控制器的大多数功能都由操作系统接手。视图的理念发生了变化:之前它只是一个小部件,现在它是一个众多小部件的组合;一个视图可以包含另一个视图。视图在某种意义上变成了双向的,它响应用户操作并显示模型数据。


前端世界中视图的理念与这个概念非常相似。在 Web 环境中,视图是一个完整的页面。


经典 MVC 变得过时且难用。为了适应这些不断变化的环境,Dolphin 团队在 1995 年正在寻找一种创建用户界面的新模型。Dolphin 团队如何找出新设计的历史可以参阅这里这里的记录,本文不再赘述。


总而言之,该团队最终将 MVC 模型旋转了 60 度,他们称其为 Twisting the triad。于是我们有了 MVP。


在协作方面:


  1. 表示器(Presenter)监督表示逻辑。表示器可以直接更改视图。视图将用户事件委派给表示器

  2. 根据实现,视图注册到模型上,并依赖表示器处理复杂逻辑;或者在其他情况下,视图只依赖表示器处理一切。


正如 Martin Fowler 在关于GUI架构的论文中总结的那样,他将 MVP 实现分为监督控制器 MVP 被动视图 MVP。从图中可以看出它们的差异和各自的数据流。



MVP——模型视图表示器

MVVM——模型-视图-视图模型

MVP 很棒,有许多可能的变种和复杂的细节;但从前端应用程序的角度来看,MVVM 确实更胜一筹。在一些实现中,后者也被称为模型-视图-绑定器。MVVM 很像被动视图 MVP,但增加了数据绑定的功能。它是一种编程技术,将来自提供者和消费者的数据源绑定在一起并同步。它摆脱了我们过去需要用来保持视图和模型同步的许多样板代码。这样我们就能在高得多的抽象级别上工作了。在协作方面:


  1. 视图模型(ViewModel)是一个对象,它公开视图所使用的可绑定属性和方法。

  2. MVVM 有额外的绑定器(Binder)实体,负责使视图视图模型保持同步。每次视图模型上的属性更改时,视图都会自动更新以反映 UI 上的更改。



MVVM——Model View ViewModel


MVVM 中的数据绑定已经成为许多前端库的基础,包括 Knockout、Angular、Vue.js 和 React 等。


我们将在 Web 应用程序部分再讨论数据绑定。

进入 Web 应用程序领域

就像原始的 MVC 模式一样,出现了一种用于 Web 应用程序的模式。它被称为 Web MVC。实际上,Web 应用程序的构建和部署方式让 MVC 在 Web 端比在桌面端更加顺其自然。


社区的主要困惑是不知道桌面 MVC Web MVC 是两种不同的模式。要是 Web MVC 当初不叫这个名字,大家就会清楚多了。


Web 应用程序是分布式应用程序的子类别。虽然 MVC 对 Web 应用程序感觉更自然一些,但一般来说构建分布式应用程序是很困难的。代码的某些部分在服务器上运行,同时还要保留在客户端(例如浏览器)上。


大规模 Web 应用程序架构的重点在于确定代码的哪个部分应该在哪里执行。我们有服务端驱动的应用程序或富客户端驱动的应用程序。在两者之间,我们可以无限自由组合。


在 MVC 的语境中讨论 Web 应用程序时有三个不同的数据周期,因此有三个 MVC 实现:服务端 MVC、浏览器内部的 MVC 和前端 MVC。浏览器负责三种类型交互的中介:


  1. 在客户端(JS+HTML)代码和服务端代码之间。

  2. 在用户和服务端代码之间。

  3. 在用户和客户端代码之间。


浏览器有自己的模型、视图控制器。作为开发人员,我们不必担心浏览器 MVC。

服务端 MVC,亦即 2 号模型

服务端 MVC 的第一个众所周知的实现是 Sun Microsystems 针对 Java Web 应用程序的 2 号模型(Model 2)



服务端 MVC——前端视角


这个 MVC 与传统的 MVC 非常相似,但由于数据跨越客户端和服务端边界时数据流周期时间呈指数级上升,因此前者多出来很多复杂性。需要注意的一些事项有:


  • 桌面 MVC 有两个数据周期,而 Web MVC 有三个数据周期

  • 有两种视图周期。首先是客户端视图周期,例如滚动事件、键盘输入等。其次是服务端视图周期,例如页面刷新、超链接激活等。

  • 最后我们有一个模型周期,它在通过客户端-服务端边界时有额外的时间复杂度。

  • 前端控制器(Front Controller):是通常由底层技术栈提供的组件,用于处理 HTTP 请求调度。例如 Java Web 应用程序中的 Servlet 容器、ASP.NET 中的 IHttpHandler 或 Node.js 中的HTTP.Server类


今天的 SSR——服务端渲染则是完全不同的概念。然而事实并非如此。由于整个 HTML/内容是由服务端生成的,并且不涉及客户端 JavaScript 代码,因此完全使用服务端 MVC 构建的 Web 应用程序仍被视为 SSR。

超越服务端

从这里开始就有意思了。不知不觉中,几乎所有浏览器都开始提供 JavaScript 引擎。在我看来正是 AJAX 改变了 Web 应用程序。谷歌是最早的实践者,在其邮件客户端和地图应用中采用了这项技术。


这个世界里由服务端 MVC 生成 HTML+JavaScript。JS 代码遍布所有页面。JavaScript 主要用来减少服务端视图周期以改善用户体验。表单提交、输入验证等内容由客户端代码处理。



客户端有了自己的模型会发生什么?


它是 Web 应用程序历史上最流行的架构。大多数 B2C 应用程序、SEO 友好网站,尤其是使用 CMS(内容管理系统)构建的网站都在使用它。客户端代码量取决于应用程序的需求。


这样的架构从未真正标准化,因此没有名称。它一直在渐进发展,仍被认为是 Web MVC 的扩展。ASP.NET MVC、Java Struts、Python Django、Ruby ROR 和 PHP CodeIgniter 是流行框架的一些例子,它们大量使用服务端 MVC Web MVC


当然,这种标准模式还有很多变体,但它们对当代前端架构没有任何实际影响,可以忽略。

基础 RIA——富互联网应用架构

了解过这些背景,我们现在准备讨论当代前端架构。当代前端架构主要解决的是构建 RIA——富互联网应用程序的问题。RIA 的确切定义并不存在,因为很多事物都能用它描述。但总的来说,RIA 富 Web 应用是应用程序的一个类别,其中应用程序严重依赖客户端代码,并且它们的用户体验非常接近桌面应用程序。它主要使用支持 SPA(单页面应用程序)的框架构建。来自 Web MVC 的服务端视图周期的数据流这里不存在。它通常只有一个初始 HTML 页面,然后使用客户端代码和路由解决方案来渲染后续页面。


构建 RIA 是一项复杂的操作,这种操作从以前基于桌面的 GUI 架构学习发展而来。视图模型、观察者、组件等就是从这些架构中借用的一些理念。Oliver steel在他 15 年前的博客文章中(相信我,它是最出色的文章之一),为理解 RIA 数据流提供了很好的参考架构。



客户端变重了——SPA 的时代


RIA 参考架构和 Web MVC 之间最显著的区别是前者的顶层架构中缺少控制器视图。然而字面意义上讲它们并没有消失。如果我们看一下底层,控制器和视图仍然存在,只是承担的角色大大缩减了。后端主要是 API 驱动的。视图仅限于生成 JSON,控制器负责编排传入请求并将其映射到适当的业务工作流。

GUI 模式很难?

如果你已经深入探索了前面的模式,那么你将意识到 GUI 模式与其他软件工程模式有所不同。以可复用的面向对象软件的元素为例:大多数模式都独立于技术或语言,但 GUI 模式并非如此。这些模式适用于人机交互的边界。用户副作用本质上是模式的一部分。(注意:可复用的面向对象软件的元素已经指出了经典 MVC 的本质)


GUI 模式适用于 HCI——人机交互的边界。用户和副作用本质上是模式的一部分。


因此,在不考虑基础框架或语言的情况下几乎不可能在理论上讨论它们。到目前为止,我们可以在相当高的抽象级别上探索这些模式。但当我们接近本文的核心时,我们将依靠不同的库或框架来描述这些模式。


大多数 Web UI 模式可以分为三个阶段,即进化、变革和当代阶段。



前端图谱——宏观视角


进化模式只是服务端 MVC 的扩展。它们并不会试图改变方向或发明全新的事物。它们会一步一步地改进来补足现有应用程序的缺陷。而变革模式是将前端应用开发与服务端驱动的工作流程分离的那些理念。它们的到来标志着 SPA 应用的兴起。当代模式就是对这些变革模式的二次修正,也是前端社区前进的大方向。

DOM 注入算法

由 jQuery 引入和掌握的这项技术是编写大规模客户端应用程序的真正起步,尽管 jQuery 并未真正解决架构问题。它旨在简化当浏览器中存在太多不一致时的 DOM 操作。它提供了与浏览器无关的 API。


虽然我不觉得这是有意为之,但 jQuery 把 DOM API 简化到了很难将其与正常的语言 API 区分的程度。这反过来又让开发人员将 DOM API(视图层)与业务逻辑(模型)完美地混合在一起。


需要指出的一点是,它仍然在同一服务端 MVC 的上下文中。这只是一个扩展。没有真正的控制反转。视图/页面的总体控制仍然由服务端代码驱动。



jQuery——HTML 代码



jQuery——DOM 注入算法


在上面的代码片段中,模型视图表示器/控制器被混合成一个单体代码结构。当模型只包含一个属性时就是这种情况。想象一下,尝试构建一个没有服务端视图周期的 Web 应用程序(比如 SPA),做这样的事情是没有意义的。与 DOM 交互的代码简洁地注入了其他应用程序逻辑,这就是为什么它被称为 DOM 注入算法(注意:我不确定 DOM 注入这个术语是不是什么规范名称)

Backbone.js——MV*

正如我们在 jQuery 中看到的那样,在开发应用程序时显然缺少构建和组织代码的方法。于是 Backbone.js 应运而生,成为了新的进化解决方案。它是首批将 MVC 风格带给客户端的库之一。



Backbone.js 数据流


我们看一看 Backbone 数据流示意图,就可以清楚地看到模型视图,但是没有控制器的等效对象。模式在不断发展,客户端 MVC 只是之前 MVC 架构的进化。在这个进化过程中,大多数 JavaScript 社区都同意模型视图的定义,但针对控制器没有形成共识。考虑到客户端环境,控制器的理念并不合适。控制器留待进一步解释。


至于 Backbone 而言,控制器不存在;那么它适合哪里?是 MVC、MVP 还是 MVVM? 借用服务端 MVC 的定义,控制器有两个职责:以传入的 HTTP 请求的形式响应用户操作,并协调模型以生成视图(HTML 页面)。在 Backbone 的情况下,视图路由器共享这些职责,但是缺少独立的控制器表示器的概念。


一些开发人员认为 Backbone 是 MVP,其中视图类似于表示器,模板(Template)是视图,而 Backbone 模型集合(Collection)构成模型

正如Addy Osmani在他的博客中所说,最好不要强行把 Backbone 归类到任何特定的设计模式。设计模式应被视为应用程序结构的灵活指南,由此看来 Backbone 既不像 MVC 也不像 MVP。相反,它借鉴了多种架构模式中的一些最佳概念,并创建了一个运行良好的灵活框架。


这就是 MV 或模型-视图-其他*的诞生历程。强烈推荐 Addy Osmani 的博客文章:理解 MVC 和 MVP——适合JavaScript和Backbone开发人员


与之前的 jQuery 相比,Backbone 可以生成更加结构化的代码。



Backbone.js 中的视图模板



在 Backbone.js 中创建一个模型



在 Backbone.js 中创建一个视图实例



在 Backbone.js 中链接视图和模型


前文中我将 Backbone 称为下一个进化解决方案。原因是它只是补充并扩展了服务端 MVC。例如,如果我们的后端是 RESTful,意味着前端代码只是用来表示服务端模型的手段,那么 Backbone 已预置为与 API 同步:



Backbone.js 中自动生成的集合方法


而且 Backbone 中还有许多其他小型约定,感觉只是扩展而已。总之,Backbone 可能不是当时唯一的解决方案,但它在代码结构和组织领域确实做出了开创性的工作。像 jQuery 一样,它被许多产品采用。

Knockout.js——前端的数据绑定

Knockout.js 是我们基本模式的最后一个案例。它旨在为 JavaScript 实现 MVVM——模型-视图-视图模型。它也确实做到了。Backbone 解决的是代码组织和结构的问题,而 Knockout 是在声明式数据绑定的帮助下有效地实现视图层。声明式绑定的优点与其他声明式编程结构相同:


  1. 易读:声明式代码易于编程

  2. 减少样板:绑定允许我们在视图模型更改时自动更新 DOM,并在视图通过用户输入更改时更新视图模型

  3. 可观察:Knockout 在事件之上提供更高级别的抽象。这允许 Knockout 自动跟踪视图模型 props 之间的依赖项。如果需要,我们可以注册可观察属性。



Knockout.js 视图——双向绑定



Knockout.js 中的视图模型——使用计算属性响应


虽然 Knockout 为视图视图模型提供了定义良好的结构,但却没关注应用程序模型的问题。这使得 Knockout 高度专注、可以广泛适应,因为它可以用作库而非框架。我见过有人用它构建迷你 SPA 应用程序,其中 Web 应用程序有多个页面,每个页面都是一个小型的 Knockout 应用。这个StackOverflow答案清楚地定义了 Knockout 的 MVVM 实现的范围。


通常假设 Knockout 模型驻留在服务端。视图模型只是使用 Ajax 或等效方式询问服务端模型。


它在 DOM 更新用途上取代了 jQuery 和像 Handlebars 这样的模板解决方案,但仍然使用 jQuery 来制作动画、Ajax 等实用程序。与 Backbone 结合后,它可以作为 MVVM 模式的完整实现。理论上讲这可能已成事实,但在此之前,这些概念已经被下一代工具链吸纳过去了。


接下来 Angular 1、Aurelia、Ember.js 等代表的变革旅程开始了。


由于它与.NET 世界紧密相关,因此被广泛用于ASP.NET MVC 应用程序中。像 Backbone 一样,它是另一种进化解决方案,针对的是稍微不一样的问题。而且客户端代码依旧只是服务端 MVC 模式的扩展。服务端仍然是主导架构。彼时 Backbone 和 Knockout 常被拿来对比,但实际上它们是免费的解决方案。


Knockout Backbone 都是 JavaScript 库。不知何故,Backbone 被视为一个框架。为什么?这里没有确定的答案,但可能是因为视角不同。由于强调代码结构,Backbone 始终采用更高级别的抽象处理。此外,Backbone 从没想过要取代无处不在的 jQuery(即使在 2019 年,最流行的 100 万个网站中有 7 成都在使用 jQuery),而 Knockout 与核心 jQuery 功能高度重合(比如 DOM 操作),这自然让 Knockout 举步维艰。因此与 Backbone 相比,Knockout 的应用被大大局限了。但它仍然是前端社区首批实现的声明式数据绑定之一,值得在这里专门提到它。

Angular 1——给我控制权

jQuery 对 DOM 意味着什么,Angular 1 就对一般意义的前端生态系统有着同样的影响。它永久改变了构建大规模客户端应用程序的概念。作为一个框架,它引入了许多概念——模块系统、依赖注入、控制反转和更简单的数据绑定等。


曾几何时,选择正确的 JavaScript 库并为前端构建完美的技术栈仍然是一件痛苦的事。Angular 1 提供了一种更简单但有凝聚力的替代方案。Ember.js 和其他类似的框架也可以这么说,但是 Angular 1 的普及度是完全不同的层面,称得上是那个时代的选择。。


从某种意义上说 Angular 1 是变革解决方案,它不再是对服务端 MVC 的简单扩展,而是在页面上洒满了客户端代码。Angular 1 使 SPA 成为构建下一代用户体验的几乎是事实上的一流解决方案。

是框架还是库?

先前的解决方案更像是库而不是框架。毫无疑问,Angular 1 是一个明确定义的框架。框架和库之间的关键区别是 IOC——控制反转。作为框架,Angular 1 具备:


  1. 明确定义的 MVVM:Angular 1 具有清晰的模型视图视图模型对象。

  2. 依赖注入(DI):Angular 1 对 DI 提供一流支持,为模型对象提供生命周期管理。在 Angular 1 中,应用程序的模型使用服务(Service)实现。默认情况下服务是一个单例实体,对于模型对象来说通常很理想。

  3. 数据绑定和更改检测:数据绑定是声明式的,更改检测是自动的。数据绑定是 MVVM 必要的组件。绑定是双向的。此外更改检测几乎是自动的(Angular 1 真的很神奇)。它为开发人员省去了许多样板代码。事件的使用和整体注册机制往往也会简化。这在基于 MVC 的系统中非常普遍。事件还会降低代码可读性,因为某些工作流的数据流分布在代码中。

  4. 模块系统:Angular 1 引入了特定于框架的模块系统。模块是几乎所有语言的代码组织的基础。JavaScript 直到 2015 年才有模块系统(浏览器直到 2018 年才支持它)。Angular 在组织方面领先时代。


与此同时,Angular 1 也因其引入的复杂性而受到批评。最重要的批评指出它是在服务端构造之后建模的。前端开发人员并不习惯这样。有些缺陷无法忽视:


  1. 命名空间冲突:虽然 DI 很棒,但它是使用全局命名空间的 Service Locator 模式实现的,于是服务必须添加前缀。

  2. 双向数据绑定:当时这可能是个好主意,但之后人们意识到它并不能真正扩展。特别是 React 的兴起使双向数据绑定成为可选项。不小心的话,双向绑定可以带来许多面条代码。

  3. 令人困惑的术语:Angular 1 使用的一些术语显然令人困惑。例如,Angular 1 用 $scope 作为视图模型,但它也有控制器可以扩充 $scope 对象。可能正确的名称可以是 VMFactory 之类。此外,Angular 1 有三种服务配方,其中一种名为 Service


还有许多其他小问题。另外,Angular 2 或简称 Angular 是一个彻底的更新,它就像一个全新的框架。除了名字和少量概念之外,两代版本之间找不到什么共同点。



Angular.js——概览


多年来,Angular 1 发布了一些小版本更新,修复了许多复杂的小细节。最重要的是增加了组件模型,组件模型是前端世界大多数理念的交汇点。


Angular 1 在前端社区的遗产影响深远。它的优缺点帮助社区了解了软件架构的重要性,并为编写可扩展应用程序的工作提供了基准。它的缺点/不足成为了未来架构解决问题的基础。


原文链接


https://blog.webf.zone/contemporary-front-end-architectures-fb5b500b0231


2019-09-26 17:184701

评论

发布
暂无评论
发现更多内容

企业应推动数据全生命周期运营,充分释放数据价值

用友BIP

TikTok矩阵怎么玩?

Ogcloud

云手机 tiktok云手机 tiktok运营 TikTok养号 tiktok矩阵

2025世亚软博会(北京展)正式开启预定

AIOTE智博会

软件展会 软博会 世亚软博会 北京软博会

央国企“严选”!天翼云夺得IaaS+PaaS市场桂冠!

天翼云开发者社区

云计算 云服务 天翼云

新业财税资档一体化:存量资产盘活就选用友BIP超级版

用友BIP

90后斩获多家名企offer的小哥哥,做对了什么?

霍格沃兹测试开发学社

从消息中间件架构发展趋势,探讨物联网平台如何支持亿级设备推送?

华为云开发者联盟

IoT Apache Pulsar 消息中间件 华为云IoTDA

Pytest 并行与分布式运行测试用例的实现与优化

测吧(北京)科技有限公司

测试

落子全球,亚马逊云科技让中国企业出海“触手可及”

亚马逊云科技 (Amazon Web Services)

威睿第100万台电驱产品下线,全速迈上新能源驱动发展新台阶

科技热闻

61支队伍入围!用友第六届企业数智化应用开发大赛决赛名单公布

新消费日报

推理王者o1到底怎么落地?

脑极体

AI

载誉而归!天翼云荣获第23届中国IT用户满意度大会多项殊荣

天翼云开发者社区

云计算 IT 云服务

重磅发布 | 末等调整和不胜任退出数智化解决方案

用友BIP

鸿蒙开发实战:轻松配置多环境目录,实现高效应用部署

王二蛋和他的张大花

鸿蒙

Netty 如何自动探测内存泄露的发生

不在线第一只蜗牛

Java 内存泄露 Netty

鸿蒙开发实战:智能日志定位与高效调试技巧

王二蛋和他的张大花

鸿蒙

Pytest-ordering:自定义 Pytest 测试用例执行顺序的指南

测吧(北京)科技有限公司

测试

Robotaxi三国杀

脑洞汽车

AI

数字先锋| 小平台如何展现大智慧?快来一睹“遵”容!

天翼云开发者社区

云计算 云服务

全国数据标准化技术委员会成立,企业该对数据”下狠手”了

用友BIP

探索微店API接口:如何高效获取商品详情数据

代码忍者

API 接口 pinduoduo API

别再被多线程搞晕了!一篇文章轻松搞懂 Linux 多线程同步!

快乐非自愿限量之名

Linux 多线程

spring-关于组件的注入及获取流程

EquatorCoco

Java spring 后端

舞台已就位!坐等AI玩家集结!

天翼云开发者社区

云计算 AI 天翼云

全链路压力测试:确保系统在高负载下的稳定性与响应能力

测吧(北京)科技有限公司

测试

鸿蒙开发实战:灵活定制编译选项,打造高效应用

王二蛋和他的张大花

鸿蒙

鸿蒙开发实战:深度解析网络管理技巧与实战应用

王二蛋和他的张大花

鸿蒙

ColPali: 基于 PaliGemma-3B 和 ColBERT 策略的视觉检索器

吴脑的键客

人工智能 搜索算法

机器学习与AI|如何利用数据科学优化库存周转率?

Altair RapidMiner

人工智能 数据分析 altair RapidMiner

为什么真全闪分布式存储离不开 RoCE/RDMA 流控技术?

XSKY星辰天合

#分布式存储 流控技术

深度解读当代前端架构演进与趋势(上)_大前端_Harshal Patil_InfoQ精选文章