有梦想,有干货,微信搜索【大千世界】关注这位凌晨还在洗碗的洗碗智者。本文已收录到GitHubhttps://github.com/qq449245884/xiaozhi,里面有完整的测试站点、资料和我的一线厂商访谈系列文章。本文为翻译,原作者为Chris,Bitski首席前端工程师,Ember.js核心团队成员,曾任LinkedIn、Addepar、Ticketfly(现EventBrite)前端工程师。第一人称指的是大佬。早在2012年,我就开始主要使用JavaScript编写代码。我曾经从头到尾制作过一个PHP应用程序,一个基本的CMS和本地企业的网站,公司决定重写它并添加一些功能。项目经理希望我使用.NET,部分原因是他知道这一点,但也因为他希望该应用程序感觉像本机应用程序——没有页面刷新或长时间等待操作。经过一些研究和原型设计,我说服了经理,有一个全新的JS框架刚刚开始出现,可以做这些事情。我选择的第一个框架实际上是Angular1。在我遇到路由器的一些问题之前,我已经构建了一个相当大的应用程序并使用了FuelPHP的后端——每当重新渲染子路由/出口时,它就会闪烁,感觉就像在设计没有考虑这种情况。后来有人向我推荐了RubyonRails+Ember。试用后,我觉得效果很好。我也喜欢这两个框架的idea,我喜欢这些社区生态,和当时的alternatives相比,总的来说,是很有生产力的。从那时起发生了很多变化-框架已经出现并发展了很多。可以在浏览器中使用JavaScript构建应用程序的想法从边缘变成了标准实践。我们构建的基础设施已经完全改变,带来了许多新的可能性。在此期间,思想之间也存在相当多的竞争和冲突。使用哪种JavaScript框架、如何编写CSS、函数式编程与面向对象编程、如何最好地管理状态、哪种构建系统或工具最灵活、最快速等等。回想起来很有趣,我们经常争论错误的事情而忽略了一些前瞻性的东西,这当然是事后诸葛亮。所以我想做一个回顾,回顾过去几十年的JavaScript发展,看看我们走了多远。我们可以大致将其分为四个主要时代。:PrimitiveEraFirstFrameworkComponent-CentricViewLayerFull-StackFramework每个时代都有自己的主题和核心矛盾,同时也在努力吸取重点教训,稳步前行。今天,争论仍在继续。网络是否变得过于臃肿?一般的网站真的需要用React写吗?我们甚至应该使用JavaScript吗?当然,现在不能代表未来,现有的框架很可能在未来被取代。但是,它也是基于一些现有的观点来帮助我们前进。原始年JavaScript于1995年首次发布。就像我上面提到的,我在2012年开始编写JS,差不多20年后,接近我所说的第一个框架时代的开始。你可能会争辩说我可能在这里掩盖了很多历史,而且这个时代可能被分解成许多子时代,每个时代都有自己的模式、库、构建工具等。也就是说,我不能写关于我没有经历过的事情。当我开始编写前端应用程序时,新一代框架才刚刚开始成熟。Angular.js、Ember.js、Backbone等。在此之前,最先进的是像jQuery和MooTools这样的库。这些库在当时非常重要——它们帮助消除了浏览器实现JavaScript的方式之间的差异,这非常重要。例如,IE实现事件的方式与Netscape完全不同——冒泡事件与捕获事件。这就是为什么我们今天的标准最终实现了这两种浏览器,但在此之前,我们需要使用库来编写适用于两种浏览器的代码。这些库主要用于制作小型、独立的用户界面组件。大多数应用程序的业务逻辑仍然通过表单和标准HTTP请求发生——在服务器上呈现HTML并将其提供给客户端。在这个时代,没有什么构建工具可言,至少据我所知是这样。当时的JavaScript没有模块(至少没有标准模块),所以没有任何方法可以导入代码。一切都是全球性的,组织这些东西非常困难。在这种环境下,JS通常被视为一种玩具语言,而不是用来编写成熟应用程序的语言,这是可以理解的。那时我们做的最常见的事情是投入jQuery,为一些UI小部件编写一些脚本,然后瞧瞧。随着时间的推移和XHR的引入和流行,人们开始将他们的部分UI流程放到一个页面中,特别是对于需要在客户端和服务器之间进行多次来回交互的复杂流程,但应用程序的大部分内容仍然存在在服务器上。这与移动应用程序开始出现时发生的情况形成鲜明对比。从一开始,iOS和Android上的移动应用程序就是用ObjectiveC和Java等严肃语言?编写的完整应用程序。此外,它们完全是API驱动的——所有UI逻辑都在设备上,与服务器的通信纯粹是数据格式。这导致了更好的用户体验和移动应用程序的爆炸式增长,直接导致了我们今天关于移动或网络哪个更??好的争论。在JavaScript中做这一切起初被认为是可笑的。但随着时间的推移,这些应用程序开始变得更加雄心勃勃。社交网络增加了聊天、DM和其他实时功能,Gmail和GoogleDocs表明可以在浏览器中编写等同于桌面的应用程序,并且越来越多的公司转向编写Web应用程序,因为Web无处不在,并且更好。易于长期维护。这推动了行业向前发展——现在很明显JS可以用来编写重要的应用程序。那时JavaScript不具备今天的所有功能,一切都是全局的,通常需要手动下载每个外部库并将其添加到静态文件夹中。那时没有NPM,不存在模块,JS也没有今天一半的功能。在大多数情况下,每个应用程序都是自定义的,每个页面都有不同的插件设置,每个插件都有不同的系统来管理状态和渲染更新。为了解决这些问题,最早的JavaScript框架开始出现。第一个框架大约在2000年代末和2010年代初,第一个专门用于编写完整客户端应用程序的JS框架开始出现。这个时代的几个知名框架:Backbone.jsAngular1Knockout.jsSproutCoreEmber.jsMeteor.js当然还有很多,而且可能在某些圈子里更大一些。这些是我记得的,主要是因为小明用它们来打码,比较流行。这是一个正在进入未知领域的生成框架。一方面,他们试图做的事情非常雄心勃勃,很多人认为它永远不会真正奏效。有许多反对者认为单页JS应用程序(SPA)从根本上来说更糟糕,并且在很多方面他们是正确的-客户端呈现意味着机器人无法轻易抓取这些页面,用户甚至必须等待几秒钟几分钟才能开始绘制应用程序。很多这些应用程序都是可访问性的噩梦,如果关闭JavaScript,则根本无法运行。另一方面,我们没有使用JS构建完整应用程序的经验,因此关于最佳方法存在大量相互竞争的想法。大多数框架都试图模仿其他平台上的流行做法,因此几乎所有框架最终都成为Model-View-*的某种迭代。模型-视图-控制器、模型-视图-生产者、模型-视图-视图模型等。但从长远来看,这些都不是真正成功的——它们不是特别直观,而且很快就会变得非常复杂。这也是我们真正开始尝试如何编译JavaScript应用程序的时候。Node.js于2009年发布,NPM在2010年紧随其后,引入了(服务器端)JavaScript包。CommonJS和AMD争论如何最好地定义JS模块,而Grunt、Gulp和Broccoli等构建工具争论如何将这些模块组合成可交付的最终产品。在大多数情况下,这些都是非常通用的任务运行器风格的工具,它们可以真正构建任何刚好用于构建JavaScript的东西——以及HTML、CSS/SASS/LESS和许多其他进入Web应用程序的东西。然而,我们从这个时代学到了很多:基于URL的路由是基础。没有此路由的应用程序会破坏网络,因此需要在框架中从一开始就考虑到这一点。通过模板语言扩展HTML是一个强大的抽象层。即使它有时可能有点笨拙,但它使UI与状态保持同步变得容易得多。SPA表现不佳,而且网络有许多原生应用所没有的额外限制。我们需要把所有的代码都发布到web上,让它JIT,然后运行来启动我们的应用,而本地的应用已经下载编译完成,这是一个巨大的任务。作为一种语言,JavaScript存在很多问题,它确实需要改进才能使事情变得更好——单靠框架无法做到这一点。我们绝对需要更好的构建工具、模块和打包来大规模编写应用程序。总的来说,那个时代是富有成效的。尽管存在缺点,但随着应用程序复杂性的增加,将客户端与API分离的好处是巨大的,并且在许多情况下,由此产生的用户体验是惊人的。除非有特殊情况,否则这个时代可能会继续下去,我们还在迭代MV*风格的想法。但随后一颗小行星突然出现,打破了现有的范式,引发了一场小型灭绝事件,将我们推向了下一个时代——一颗名为React的小行星。以组件为中心的视图层我不认为React发明了组件,但老实说,我一开始并不知道它们是从哪里来的。但至少早在.NET中的XAML时代,Web组件就开始作为规范发展。最后没关系——想法一出,各大框架很快就采纳了。事后看来,这是完全有道理的——扩展HTML,减少长期存在的状态,将JS业务逻辑直接绑定到模板(无论是JSX还是Handlebars或指令)。基于组件的应用程序消除了完成工作所需的大部分抽象,并显着简化了代码生命周期——一切都与组件的生命周期相关,而不是应用程序的生命周期,这意味着作为开发人员,您需要考虑的事情要少得多.然而,当时还有另一个转变:该框架开始吹嘘自己是一个“视图层”,而不是一个成熟的框架。他们没有解决前端应用程序所需的一切,而是专注于解决渲染问题。其他问题,例如路由、API通信和状态管理,则留给用户处理。这个时代著名的框架有:React.jsVue.jsSveltePolymer.js等等。现在回想起来,我认为这是一个流行的第二代框架,因为它做了两件主要的事情。它极大地缩小了范围。该框架的核心不是试图预先解决所有这些问题,而是专注于渲染,并且可以为更广泛的生态系统中的其他功能探索许多不同的想法和方向。有很多不好的解决方案,但也有好的解决方案,为下一代从精华中挑选最好的想法铺平了道路。这使我们更容易接受它们。采用完整的框架来接管整个网页意味着重写大部分应用程序,这对于现有的服务器端单体来说是不可能的。使用像React和Vue这样的框架,您可以将它们的一小部分一次放入一个小部件或组件的现有应用程序中,从而允许开发人员逐步迁移他们现有的代码。这两个因素导致了第二代镜架的快速发展使第一代镜架黯然失色,从远处看这一切似乎都合情合理,顺理成章。但当时身处其中是一种令人沮丧的经历。首先,当我们在工作中争论使用哪个框架,或者我们是否应该重写我们的应用程序时,我们并不经常遇到这样的框架。相反,很多时候是“更快!”或“它更小!”或“这就是您所需要的!”。还有关于函数式编程与面向对象编程的争论,许多人指出FP是我们所有问题的解决方案。公平地说,这些都是真的。仅查看框架更小(起初),更快(最初),并且满足您的所有需求(如果您自己构建或缝制很多东西)。当然,函数式编程模式解决了大量困扰JavaScript的问题,我认为平均而言,JS因为它们而变得更好。然而,现实是没有灵丹妙药。应用仍然庞大、臃肿和复杂,状态仍然难以管理,路由和SSR等基础问题仍然需要解决。对于我们中的许多人来说,人们想要的似乎是放弃试图解决所有这些问题的解决方案,并用让读者自己解决的解决方案取而代之。根据我的经验,这也是工程团队的常见做法,他们会乐于接受变化以交付新产品或功能,然后不会花时间来完全开发所有这些附加功能。结果是围绕这些视图层构建的自制框架本身臃肿、复杂且很难操作。我认为人们对SPA的很多问题都来自这种分散的生态系统,这种生态系统恰好发生在SPA使用量激增的时候。我仍然经常遇到一个新站点,它不能正确地进行路由或不能很好地处理其他小细节,这绝对令人沮丧。但另一方面,现有的第一代全业务框架并没有很好地解决这些问题。部分原因是巨大的技术债务包袱。第一代框架是在ES6之前,在模块之前,在Babel和Webpack之前,在我们弄清楚很多东西之前构建的。迭代进化非常困难,完全重写它们,就像Angular对Angular2所做的那样,会扼杀他们社区的势头。因此,当涉及到JavaScript框架时,开发人员陷入了两难境地——要么选择一个开始显老的一体化解决方案,要么跳入框架的免费、DIY部分并希望最好的。当时非常沮丧,但最终产生了很多创新。随着这些框架找出它们的最佳实践,JavaScript生态系统发展非常迅速,并且发生了一些其他关键变化。像Babel这样的转译器成为常态,并帮助使语言现代化。与其等待多年等待功能标准化,不如今天就使用它们,并且语言本身开始以更快、更迭代的速度添加功能。ES模块已标准化,因此我们最终开始围绕它们构建现代构建工具,如Rollup、Webpack和Parcel。基于导入的捆绑正在慢慢成为常态,即使对于样式和图像等非JS资源也是如此,这极大地简化了构建工具的配置,使它们更精简、更快、更全面。随着越来越多的API被标准化,Node和Web标准之间的差距正在缓慢但稳定地缩小。SSR最初是一种真正的可能性,然后是每个严肃的应用程序都在做的事情,但每次都是作为自定义设置。释放边缘计算,为基于JavaScript的服务器应用程序提供SPA在分发/响应时间方面的优势(Spa过去开始加载速度更快,因为它们是CDN上的静态文件,即使它们需要更长的时间才能完全加载和结束)。在这个时代结束时,仍然存在一些问题。状态管理和响应仍然是(并且是)棘手的问题,尽管我们有比以前更好的模式。性能仍然是一个棘手的问题,尽管情况正在改善,但仍然存在许多臃肿的SPA。可访问性情况也有所改善,但对于许多工程组织而言,这仍然常常是事后才想到的。但是这些变化为下一代框架铺平了道路,我想说我们现在正在进入下一代框架。全栈框架在我看来,最后一个框架时代真的悄悄来临了。我想这是因为我在过去4年左右的时间里深入挖掘了Ember渲染层的内部结构,试图解决上述影响它作为第一代框架的技术债务(仍然)。但也是因为它更微妙,因为所有这些第3代框架都是围绕上一代的视图层框架构建的。这些框架包括:Next.js(React)Nuxt.js(Vue)Remix(React)SvelteKit(Svelte)Gatsby(React)Astro(Any)这些框架开始于视图层的成熟和整合。现在我们都同意组件是建立在核心基础之上的,开始标准化应用程序的其余部分是有意义的——路由器、构建系统、文件夹结构等。慢慢地,这些元框架开始构建相同的第一代一体化解决方案开箱即用的功能,从各自的生态系统中挑选最佳模式,并在它们成熟时将它们结合起来。然后他们更进一步。在此之前,SPA一直只关注客户。SSR是每个框架都希望解决的问题,但只是作为一种优化,一种在最终加载兆字节的JS时最终将被替换的渲染方式。只有一个第一代框架敢想得更远,Meteor.js,但它的同构JS的想法从未真正实现过。但随着应用程序规模和复杂性的增加,人们重新审视了这个想法。我们注意到将后端与前端配对实际上非常有用,这样您就可以执行某些操作,例如为某些请求隐藏API机密、在返回页面时修改标头以及代理API请求。随着Node和Deno实施越来越多的Web标准,并且服务器端和客户端JS之间的差距每年都在缩小,它开始看起来并不是一个疯狂的想法。将其与边缘计算和令人惊叹的工具结合起来,就会产生一些不可思议的潜力。最新一代的框架充分利用了这种潜力,无缝地融合了客户端和服务器,我怎么强调它的感觉都不为过。在过去与SvelteKit合作的9个月里,我不知道有多少次坐下来对自己说,“这是我们应该一直做的事情。”下面是我最近遇到的一些任务,有了这个设置,这些任务就变得异常简单。将服务器端OAuth添加到我们的应用程序,以便身份验证令牌永远不会离开服务器,以及在向我们的API发送请求时添加令牌的API代理。将某些路由直接代理到我们的CDN,以便我们可以托管在任何其他框架中构建的静态HTML页面,允许用户制作自己的自定义页面(我们为某些客户提供的服务)。当我们需要使用需要密钥的外部服务时添加几个不同的一次性API路由(不需要向我们的API添加一个全新的路由并与后端人员协调)。将我们对LaunchDarkly的使用卸载到服务器端可以让我们加载更少的JS,从而降低总体成本。通过后端路由代理我们的哨兵请求,这样我们就可以捕获由于广告拦截器而未报告的错误。而这只是冰山一角。这种模式确实有很多很酷的地方,其中最大的一个就是它如何重新激发渐进式增强的想法,利用服务器和客户端的组合特性,允许客户端回退到基本的HTML+HTTP。当我开始与SPA合作时,我自己已经完全放弃了这种做法,认为它们是未来的方式,但我们有可能看到它卷土重来的世界真的很酷。这些都是新特性,根据经验,我将这些框架归类为新一代框架。以前难以或无法解决的问题现在变得微不足道,只需要对响应处理逻辑进行微小的更改。开箱即用,无需任何额外配置即可提供可靠的性能和用户体验。我们可以根据需要添加一些额外的端点或中间件,而不是构建一个全新的服务。这改变了生活。我认为这一代还解决了第一代和第二代框架及其用户之间的一些主要紧张点。它始于向零配置术语的转变,但我认为它最终是由围绕第二代框架的生态系统的成熟和稳定所驱动的,这也是一种文化转变。第三代框架现在再次尝试成为一体化解决方案,试图解决我们作为前端开发人员需要解决的所有基本问题——而不仅仅是渲染。现在,感觉社区比以往任何时候都更加一致地解决困扰SPA的所有许多问题,并且重要的是,共同努力解决这些问题。我们接下来要去哪里?总的来说,我认为JavaScript社区正朝着正确的方向前进。我们终于开发出成熟的解决方案,用于从头开始构建完整的应用程序,而不仅仅是“视图层”。我们终于开始与本地应用程序的SDK在同一起跑线上竞争,提供开箱即用的完整工具包。我们在这方面还有很多工作要做。在SPA世界中,可访问性长期以来一直是事后才想到的,在GraphQL之外,我仍然认为数据故事可以使用一些工作(不管你喜欢与否,大多数网络仍然在REST上运行)。但是趋势是对的,如果我们继续朝着共享解决方案的方向发展,我认为我们可以比以前更好地解决这些问题。我也对将这些模式进一步应用到Web平台本身背后的潜力感到兴奋。WebComponents仍在悄悄地迭代,致力于SSR和摆脱全局注册表,这将使它们与这些第3代框架更加兼容。另一方面,WebAssembly可以以令人难以置信的方式迭代此模式。想象一下能够用任何语言编写一个全栈框架。同构语言??,如Rust、Python、Swift、Java等,最终可以将前台和后台之间的障碍减少到几乎没有——只是在系统边缘的一些HTML模板(具有讽刺意味的是,这几乎给我们带来了完整的循环,尽管具有更好的用户体验)。我最大的希望是我们正在度过这个碎片化的时代,每天都有新的JS框架出现。自由和灵活性孕育了创新,但它们也会导致混乱、脱节,而且通常会从根本上破坏网络体验。当开发人员必须在50多个选项之间做出选择,并在有限的资源和紧迫的期限内将它们拼凑在一起时,这就是我们所看到的体验,而且它是有道理的。有些应用程序快速、一致、可靠且使用起来很有趣,而另一些应用程序则令人沮丧、困惑、缓慢和损坏。如果我们可以为开发人员提供更易于使用的工具,默认情况下可以做正确的事情,那么网站可能会更好一些,体验也会更流畅一些。它不会修复每个网站——再多的代码也无法修复糟糕的用户体验设计。但它会奠定一个共同的基础,这样每个站点都会开始好一点,每个开发人员都有更多时间专注于其他事情。编辑过程中可能存在的BUG无法实时获知。之后为了解决这些bug,花费了大量的时间在日志调试上。顺便推荐一个好用的BUG监控工具Fundebug。作者:Chris译者:小智来源:pzuraq原文:https://www.pzraq.com/blog/fo...交流有梦想,有干货,微信搜索【伟大的走向世界】关注这个在清晨还在刷碗清洗智慧。本文已收录到GitHubhttps://github.com/qq449245884/xiaozhi,里面有完整的测试站点、资料和我的一线厂商访谈系列文章。
