1。前言JS框架里面有很多东西要讲。相信大家更容易找到资料了解某个框架的使用和原理。有鉴于此,这部分内容将从另一个角度出发:通过回顾JS框架的发展历程,与大家探讨框架的本质,以及JS框架不断变化背后的驱动力。俗话说“知古知今”,希望大家能够对JS框架有更全面的认识,能够把握变化背后不变的逻辑,更好地应对未来新的变化.2.什么是框架在解释清楚一个东西之前,我们需要先给它下一个准确的定义。这部分我们先定义什么是框架,什么是JS框架。我们先从广义上看一下“框架”的定义:框架是框架——指的是它的约束,而架子——指的是它的支持。它是用于解决或处理复杂问题的基本概念结构。我个人很喜欢这个定义,简洁准确,框架的核心是“约束”和“支持”。如何理解“约束”框架是解决复杂领域问题的系统方法。对于复杂的问题,“银弹”往往是缺失的。每个人看待问题的角度都不一样。每个框架背后都有自己的理念。选择一个框架,就需要遵循它的逻辑和规则,在规则之内解决问题,这就是“约束”。如何理解“支撑”复杂问题通常可以拆解成一系列小问题,问题的整体解决方案就是如何解决全部或部分问题,框架的“支撑”体现在问题的定义上以及一系列解决问题的方法,是基于它能够将各个子问题的解决方案更有条理地组织起来,最终形成一个整体的解决方案。“拥”就是组织有序。如何定义JS框架的代码组织框架来解决前端特定领域的问题,约束体现在需要按照约定的结构来组织代码,支持体现在高效执行基于框架的内置机制或能力的功能。按照这个定义,JS框架涵盖了解决Web整体实现的前端应用框架、游戏引擎框架、后端服务框架等各个方面,但需要指出的是,大家通常认为的JS框架是指前端应用框架。这部分是文章的重点。顺便说一下框架和库的区别。JS库通常是解决系统构建中某个子问题的代码实现。它和框架的关系往往是被调用者(库)和调用者(框架)的关系。JS框架解决了哪些问题?Web前端技术发展非常迅速,新技术层出不穷。然而,在这些技术发展的背后,始终有一条主线——如何更高效地构建Web人机交互界面。构建复杂的Web应用首先要考虑的是如何更合理地组织代码,这关系到协作效率、可维护性、可扩展性等,本质是对生产效率的不断追求。进一步看,我们的问题域主要包括视图构建、视图状态管理、用户交互、服务器交互等。在复杂的场景下,随着表达内容和人机交互的多样性增加,如何做到兼顾效率,经验等都有很大的挑战,而这也正是JS框架要解决的问题。3.JavaScript框架的发展从TimBerners-Lee在1989年提出,到2019年3月12日,WWW迎来了它的30岁生日。也从最初的提案变成了人类社会的基础设施。从技术角度来看,在Web满足人们越来越多上网需求的同时,Web前端也变得越来越复杂:功能越来越强大,内容越来越丰富多样,运行环境越来越复杂等。从最初的小制作到现在的大规模复杂应用,不断推动着开发者寻求更高效的前端构建方式,这也是前端技术飞速发展的原动力。从Web前端的形态来看,这30年大致可以分为三个时期:只读Web时期、交互式Web时期、Web应用时期。在只读Web时期(1990~2000),Web的核心功能是将图文内容制作在线,只有少数用户使用,只能浏览内容。从技术角度来看,这个时代是Web标准的起源阶段。同时,由于内容表达需求单一,没有为JS框架的诞生提供土壤。在Web交互时代(2000~2010),越来越多的人通过Web满足自己的需求,Web内容的形式也从单一的只读图形展示演变为功能丰富的交互形式。这种演变也促进了Web开发的发展。一个新的社会分工角色演变而来——Web前端工程师。同时,有了JS框架的土壤,各种前端库和框架也逐渐诞生,但此时更专注于解决某个方向的问题:比如兼容性或组件化等;2010-至今),对于很多行业来说,Web服务已经属于基础设施,大多数人已经依赖Web能力来满足自己的需求。为了追求更好的体验和更高的效率,Web服务的构建也向客户端应用看齐,JS框架的发展逐渐覆盖了与高效构建Web前端相关的整个领域。只读Web时代1989年,为了让学校和科研机构更有效地共享信息,TimBerners-Lee提出了“WWW”提案,并于次年发明了第一个网络浏览器——WorldWideWeb。随后在1991年,HTML的第一个版本——“HTMLTags”诞生了,目标是文本、图片等信息的在线显示和互联。第一个商业浏览器诞生于1993年,来自Netscape的NetscapeNavigator。W3C的诞生要到1994年,由TimBerners-Lee创立。直到1995年,Web上的所有内容还是纯静态的,但是随着Web需求的快速增长,一些场景逐渐需要用户交互的能力,所以在1995年9月,Netscape发布了Javascript的第一个版本——LiveScript,并改变了它的3个月后命名为JavaScript。这一时期除了WWW的起源之外,还有一件值得一提的事情就是历史上第一次“浏览器大战”。在这场大战中,Netscape在前期凭借先发优势赢得了80%的市场份额。微软IE后来居上,通过与Windows的捆绑逐渐夺回优势。到2000年,微软IE的市场份额占80%以上。有意思的是,在第二次“浏览器大战”中,IE再次败下阵来,后起之秀Chrome凭借更高的性能、更好的标准兼容性和更快的迭代速度占据优势。到2019年占据70%以上的市场份额,而IE的市场份额已经下降到10%左右。对于开发者来说,在“浏览器大战”中,由于对标准的支持程度不同,甚至为了实现差异化而引入新特性,开发者需要投入大量的工作来解决兼容性问题,这也为它埋下了伏笔用于后续生成的Javascript库/框架。交互Web时代进入2000年,Internet加速发展。随着电子商务和社交网络等新平台的推出,越来越多的用户加入了互联网。此时,互联网用户群体已从最初的小众用户逐渐发展为大众用户,各大平台也越来越重视Web用户体验,开始加大对Web用户交互的资源投入。另一方面,浏览器也通过不断的升级,拥有更多的能力来支持更好的用户交互,比如异步请求能力的引入。以上供需双方为JavaScript库/框架的发展提供了土壤。现阶段Web的主流渲染方式是后端渲染。JavaScript的关键工作是实现页面的本地交互能力,例如表单验证、异步提交、图片轮播、标签切换等。这一时期的JavaScript库/框架围绕着完善与用户交互相关的基础设施开发,主要包括组件化、兼容性、工具库。组件化与其他编程语言构建人机交互界面的能力相比,Web中缺乏丰富、标准化的UI组件库。因此,这一阶段出现了一批基于组件的框架,其中DoJo(2005)和ExtJS(2007)更具代表性。这些框架的特点是提供了一个AllinOne的组件库,组件类型丰富,当然交互形式也很厚重,典型的桌面客户端风格。兼容性在“浏览器大战”的背景下,浏览器厂商之间相互厮杀,因此无论是BOM、DOM还是JavaScript,都需要做大量的兼容性工作,因此jQuery(2006)就是在这种背景下诞生的。jQuery一方面解决了大量的兼容性问题,另一方面提供了非常方便的基于CSS选择器和DOM操作能力获取DOM的方法,同时也重新封装了异步请求的API。编程范式占主导地位的时期是非常高频的操作,所以jQuery的出现大大提升了前端编程的体验和效率。当然,随着jQuery的很多能力从事实标准向正式标准演进,浏览器开始提供原生支持,前端编程模型从命令式演变为声明式,DOM的获取和操作大大减少,jQuery的使用率也迅速下降。此外,随着Chrome赢得“浏览器大战”,兼容性问题得到了很大改善,但移动端除外。这一时期工具库的原生JavaScript只支持一些比较“原始”的编码能力。与其他成熟的编程语言相比,在编程效率和体验上有着巨大的差异。各种工具库根据“原始”能力重新封装。可以最小化差异。工具库类的代表有PrototypeJS(2005)、YUI(2006)、Mootools(2007),主要封装了面向对象、事件、异步请求、数组操作等。/*PrototypeJS代码示例*///面向对象varFirstClass=Class.create({//Theinitializemethodservesasaconstructorinitialize:function(){this.data="HelloWorld";}});//异步请求Ajax.Request=Class.create(Ajax.Base,{//Overridetheinitializemethodinitialize:function(url,options){this.transport=Ajax.getTransport();this.setOptions(options);this.request(url);},//...moremethodsadd。..});//DOM和事件$$('#itemsli').each(function(item){item.observe('click',function(event){doSomethingWith(event.target);});});//数组遍历myArray.each(function(item){//Yourcodeworkingonitemhere...});当然,根据以上三个方面,并不能对很多JavaScript库/框架进行非常准确的分类。分层和可拆卸的设计可以同时兼顾各方面的需求,就像下面YUI的整体架构一样。在最近10年的Web应用时期,随着前端投入的不断增加,前端团队的话语权也越来越重要。工程化等,尤其是前后端分离的协作模式,给前端开发带来了更高的自由度和空间。前端工作职责从最初的部分动态、部分交互,逐渐扩展到整个站点的前端建设。这种变化直接带来了至少两个挑战。一是如何解决多人协作的问题。对于越来越大规模的前端工程来说,多人协作是不可避免的,而协作的关键是明确分工与配合;二是代码可维护性问题。在前端框架出现之前,部分动态的UI通常采用前端模板加命令式编程范式的方式实现。这种方式对于轻量级的UI构建尚可,但难以应对大规模的前端功能构建。,很容易写出可维护性极差的代码。这些是构建GUI应用程序时的典型问题。在Web前端出现之前,其他平台的GUI构建也存在类似的问题。解决的办法是引入合适的架构模式,将看似乱七八糟的代码分门别类,分别关注。在各自的职责范围内工作,这些架构模式包括MVC、MVP、MVVM等,其背后的核心理念是“关注点分离”。在Web前端面临类似的挑战时,自然要借鉴传统GUI构建的经验,以框架的形式引入新的架构模型来解决。在这样的背景下,真正的“框架”在前端逐渐浮现。2010年发布的Backbone.js引入了view和datamodel的概念,但不是标准的MVC实现,没有明确controller的概念,只是controller的部分职责由view承担,但这些都不是important,important是前端GUI构建的新思路和新选择。还有一点值得一提的是,Backbone.js仍然采用命令式编程范式,这与前端GUI构建和后来逐渐流行的声明式编程范式相比,在编程效率上存在明显差距。/*Backbone.js代码示例(部分)详情请访问https://backbonejs.org/docs/todos.html*/varAppView=Backbone.View.extend({el:$("#todoapp"),statsTemplate:_.template($('#stats-template').html()),事件:{"keypress#new-todo":"createOnEnter",},initialize:function(){this.input=this.$("#new-todo");this.listenTo(Todos,'add',this.addOne);this.footer=this.$('footer');this.main=$('#main');Todos。fetch();},render:function(){vardone=Todos.done().length;varremaining=Todos.remaining().length;if(Todos.length){this.main.show();this.footer.show();this.footer.html(this.statsTemplate({done:done,remaining:remaining}));}else{this.main.hide();this.footer.hide();}this.allCheckbox.checked=!remaining;},addOne:function(todo){varview=newTodoView({model:todo});this.$("#todo-list").append(view.render().el);},clearCompleted:function(){_.invoke(Todos.done(),'destroy');returnfalse;}});varApp=newAppView;});同年,AngularJS发布了第一个版本,这是与Backbone最大的不同。一方面,微软WPF的MVVM架构模式引入了VM的概念,支持视图和数据的双向绑定;另一方面,它采用了声明式的视图构建方式,大大减少了原生的DOM操作。另外,AngularJS提供了非常全面的功能(路由管理、组件化、视图模板、状态管理、后端交互、事件管理、动画等),基本达到了开箱即用的状态,用它来非常高效地构建SPA应用程序。当然,它的缺点也很明显。引入过多概念导致入门成本非常高。此外,它的“大而全”既是优势也是劣势。对于非SPAWeb场景来说,它过于臃肿。总体来说,AngularJS在解决特定场景下的前端架构问题方面非常有效,能够显着提升前端协作的效率。在AngularJS发布后的第四年和第五年,React和Vue相继发布。React发布时的目标是优化视图构建,但是随着整个生态系统的完善,React已经具备了足够的能力来支持大规模的前端应用开发。Vue借鉴了AngularJS的架构模式,同样采用了声明式的视图构建方式。与AngularJS相比,React和Vue最大的优势在于更加轻量和灵活,能够适应更多的场景。另外,上手成本也低很多,尤其是Vue,这也让后两者在近几年磨了个精光。按AngularJS。纵观近10年前端框架的变化,验证了两点。一是声明式编程范式在前端GUI构建上相对于命令式编程范式的成功。其背后的关键逻辑是研发效率的显着优势;二是渐进式框架相比AllinOne“全家桶”框架的成功,渐进式框架具有更好的灵活性,更能适应前端场景的变化。4.以史为鉴,知未来以上概述提供了近30年来前端框架发展的概况。整体演变是清楚的。Web前端从无到有,逐渐走向专业化、技术关注和挑战。也在不断变化,从最初解决DOM运行效率、兼容性、组件化等问题,到提高大规模前端协同效率等,那些能够准确把握并有效解决的框架/库问题都成功了,至少是阶段性的成功。沿着这条线往前看,前端框架的后续发展还是要看前端领域未来会面临什么样的挑战。WebvsNative在智能手机普及初期,各平台的移动端也都是以Web为主。当时,各种Web服务的m站是必备之一。随着智能手机的普及,移动APP在路径、性能、能力等方面优势明显,迅速成为移动出行的首选。在这个过程中,Web前端很大程度上淡出了移动应用的核心研发。后来随着混合开发模式的成熟,web前端逐渐参与到一些移动应用的开发中。展望未来,在从流量运营到以用户运营为核心的时期,Native主导的模式有望保持主流,用户体验将变得更加重要,尤其是对于用户长时间停留的应用。在此背景下,Web与Native如何更好的协同,如何取长补短,如何在效率和体验上进一步突破天花板,将是一个长期的挑战。在智能终端面前,更多谈论的是PC和移动终端。随着5G的完善和普及,物联网将迎来加速发展。届时,除了移动终端和PC终端之外,还会有更多不同形态的终端,如何解决这类终端的GUI需求,是否可以利用Web技术提高效率,现有的Web框架是否是物联网设备的最佳选择?随着物联网的爆发,前端框架将不得不考虑这些问题。低代码的另一个可见趋势是低代码(low/nocode)的普及。在不久的将来,大量的模块化Web开发任务很可能会通过低代码的方式来解决,比如运维、管理平台就是典型的模块化Web平台。这类平台占据了当前前端研发工作的很大比重,也是各种前端框架的重要应用场景。一旦这样的需求以低代码的方式实现,那么具体实现使用哪个框架就变得不那么重要了。在这样的背景下,很可能会诞生一些专有的框架来更高效地解决低代码领域问题。但是通用框架的场景会更加集中在非模式化的场景。在这样的场景下,对框架的灵活性和可定制性会有更高的要求。
