博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

第一章。介绍Express

Posted on 2022-06-27 21:50  pencilCool  阅读(46)  评论(0编辑  收藏  举报

翻译自:https://learning.oreilly.com/library/view/web-development-with/9781492053507/ch01.html#idm45053604170648

JavaScript的演进

在我介绍本书的主要内容之前,有必要提供一点背景和历史背景,这意味着要谈一谈JavaScript和Node。JavaScript的时代已经真正来临。从最初的客户端脚本语言,到现在不仅在客户端完全普及,而且由于Node的出现,它作为服务器端语言的使用也终于起步了。

全JavaScript技术栈的承诺是明确的:不再有上下文切换!你不再需要切换思维。你不再需要从JavaScript切换到PHP、C#、Ruby或Python(或任何其他服务器端语言)的精神齿轮。此外,它使前端工程师有能力跳到服务器端编程。这并不是说服务器端编程就是严格意义上的语言,仍然有很多东西需要学习。不过,有了JavaScript,至少语言不会成为障碍。

本书是为所有看到JavaScript技术栈的前景的人准备的。也许你是一名前端工程师,希望将自己的经验扩展到后端开发。也许你是一个像我一样有经验的后端开发者,希望将JavaScript作为根深蒂固的服务器端语言的一个可行的替代品。

如果你像我一样做了这么久的软件工程师,你会看到许多语言、框架和API开始流行起来。有的已经起飞,有的已经逐渐被淘汰。你可能为自己能够快速学习新语言、新系统而感到自豪。你遇到的每一种新的语言都会让你感觉更熟悉一些:你在这里认出了你在大学里学过的一种语言,在那里认出了你几年前的工作。当然,拥有这样的视角感觉很好,但也很累人。有时你只想完成一些事情,而不需要学习一种全新的技术,也不需要把你几个月或几年没用过的技能拿出来。

起初,JavaScript可能看起来是一个不可能的冠军。我很同情,相信我。如果你在2007年告诉我,我不仅会认为JavaScript是我的首选语言,而且还会写一本关于它的书,我一定会说你疯了。我对JavaScript有所有常见的偏见。我认为它是一种 "玩具 "语言,是供业余爱好者滥用的东西。公平地说,JavaScript确实降低了业余爱好者的门槛,而且外面有很多有问题的JavaScript,这对这种语言的声誉没有帮助。用一句流行的话来说,就是 "恨玩家,不恨游戏"。

人们对JavaScript的这种偏见是很不幸的;它使人们无法发现这种语言是多么强大、灵活和优雅。许多人现在才开始认真对待JavaScript,尽管我们现在知道的这种语言从1996年就已经存在了(尽管它的许多更有吸引力的功能是在2005年增加的)。

拿起这本书,你可能已经摆脱了这种偏见:要么是因为像我一样,你已经摆脱了这种偏见,要么是因为你本来就没有这种偏见。无论哪种情况,你都是幸运的,我期待着向你介绍Express,一种由令人愉快和惊讶的语言促成的技术。

2009年,在人们开始意识到JavaScript作为一种浏览器脚本语言的力量和表现力的几年后,Ryan Dahl看到了JavaScript作为一种服务器端语言的潜力,Node.js诞生了。这是一个互联网技术的肥沃时期。Ruby(和Ruby on Rails)从学术计算机科学中获得了一些伟大的想法,并将它们与自己的一些新想法相结合,向世界展示了一种更快速的建立网站和网络应用的方式。微软为了在互联网时代变得有意义,在.NET中做了令人惊奇的事情,不仅从Ruby和JavaScript中学习,还从Java的错误中学习,同时从学术界的殿堂中大量借鉴。

今天,由于Babel这样的反编译技术,网络开发者可以自由地使用最新的JavaScript语言特性,而不必担心疏远使用旧浏览器的用户。Webpack已经成为管理网络应用中的依赖关系和确保性能的普遍解决方案,React、Angular和Vue等框架正在改变人们的网络开发方式,使声明式文档对象模型(DOM)操作库(如jQuery)成为昨天的新闻。

这是一个令人兴奋的时代,可以参与互联网技术。到处都有令人惊奇的新想法(或令人惊奇的旧想法得到重振)。现在的创新精神和兴奋感比许多年前都要强。

介绍一下Express

Express网站将Express描述为一个 "最小和灵活的Node.js网络应用程序框架,为网络和移动应用程序提供了一套强大的功能"。不过,这到底是什么意思呢?让我们来分析一下这个描述。

最小化

这是Express最吸引人的地方之一。很多时候,框架开发者忘记了通常 "少即是多"。Express的理念是在你的大脑和服务器之间提供一个最小的层。这并不意味着它不健壮,也不意味着它没有足够有用的功能。这意味着它对你的妨碍更小,允许你充分表达你的想法,同时提供一些有用的东西。Express为你提供了一个最小的框架,你可以根据需要加入Express功能的不同部分,替换掉不符合你需要的东西。这是一股清新的空气。许多框架给你提供了一切,让你在写下一行代码之前就拥有了一个臃肿、神秘和复杂的项目。通常情况下,第一项任务就是把时间浪费在砍掉不需要的功能或替换不符合要求的功能上。Express采取了相反的方法,允许你在需要时添加你需要的东西。

灵活

最后,Express所做的事情非常简单:它接受来自客户端(可以是浏览器、移动设备、其他服务器、桌面应用程序......任何能说HTTP的东西)的HTTP请求,并返回一个HTTP响应。这种基本模式几乎描述了所有与互联网相连的东西,使得Express的应用非常灵活。

网络应用程序框架

也许更准确的描述是 "网络应用框架的服务器端部分"。今天,当你想到 "网络应用框架 "时,你一般会想到像React、Angular或Vue这样的单页面应用框架。然而,除了少数独立的应用程序,大多数网络应用程序需要分享数据并与其他服务集成。它们通常通过网络API来实现,这可以被认为是网络应用框架的服务器端组件。请注意,只用服务器端渲染来构建整个应用程序仍然是可能的(有时也是可取的),在这种情况下,Express很可能构成整个网络应用程序框架。

除了在Express自己的描述中明确提到的特点外,我还想补充两个我自己的特点。

快速

随着Express成为Node.js开发的首选网络框架,它吸引了很多运行高性能、高流量网站的大公司的关注。这给Express团队带来了压力,使其不得不关注性能问题,现在Express为高流量网站提供了领先的性能。

不偏不倚

JavaScript 生态系统的特点之一是它的规模和多样性。虽然Express通常处于Node.js网络开发的中心,但有数百个(如果不是数千个)社区包可以进入Express应用程序。Express团队认识到了这种生态系统的多样性,并通过提供一个极其灵活的中间件系统来应对,该系统可以在创建应用程序时轻松使用你选择的组件。在Express的发展过程中,你可以看到它放弃了 "内置 "的组件而选择了可配置的中间件。

我提到Express是网络应用程序框架的 "服务器端部分"......所以我们也许应该考虑服务器端和客户端应用程序之间的关系。

服务器端和客户端应用程序

服务器端应用程序是指应用程序中的页面在服务器上被渲染(作为HTML、CSS、图像和其他多媒体资产以及JavaScript)并被发送到客户端。相比之下,客户端应用程序从一个只发送一次的初始应用程序包中渲染它自己的大部分用户接口。也就是说,一旦浏览器收到最初的(通常是非常少的)HTML,它就会使用JavaScript动态地修改DOM,而不需要依赖服务器来显示新的页面(尽管原始数据通常仍然来自服务器)。

在1999年之前,服务器端应用程序是标准。事实上,网络应用这个词就是在那一年正式引入的。我认为大约在1999年到2012年之间的时期是Web 2.0时代,在此期间,最终成为客户端应用程序的技术和技巧正在被开发。到了2012年,随着智能手机的深入人心,通过网络发送尽可能少的信息成为普遍做法,这种做法有利于客户端应用程序。

服务器端应用通常被称为服务器端渲染(SSR),而客户端应用通常被称为单页应用(SPA)。客户端应用在React、Angular和Vue等框架中得到充分实现。我一直觉得 "单页 "有点名不副实,因为--从用户的角度来看--的确可以有很多页。唯一的区别是页面是由服务器发送的还是在客户端动态渲染的。

在现实中,服务器端应用和客户端应用之间有许多模糊的界限。许多客户端应用程序有两到三个HTML包,可以发送到该客户端(例如,公共界面和登录界面,或普通界面和管理界面)。此外,SPA经常与SSR相结合,以提高第一页的加载性能并帮助搜索引擎优化(SEO)。

一般来说,如果服务器发送少量的HTML文件(一般是1到3个),而用户体验到基于动态DOM操作的丰富的多视图体验,我们认为这是客户端渲染。不同视图的数据(通常以JSON的形式)和多媒体资产一般还是来自网络。

当然,Express并不关心你是在做一个服务器端还是客户端的应用程序;它很乐意扮演任何一个角色。对于Express来说,你是在为一个HTML包还是一百个HTML包提供服务,这没有什么区别。

虽然SPA已经明确地 "赢得 "了主流的网络应用程序架构,但本书从与服务器端应用程序一致的例子开始。它们仍然是相关的,而且为一个HTML捆绑包或许多捆绑包提供服务在概念上的差异很小。第16章中有一个SPA的例子。

Express的简史

Express的创造者TJ Holowaychuk将Express描述为一个受Sinatra启发的网络框架,Sinatra是一个基于Ruby的网络框架。Express借鉴了建立在Ruby基础上的框架,这并不奇怪。Ruby催生了大量伟大的网络开发方法,旨在使网络开发更快、更有效、更可维护。

就像Express受到Sinatra的启发一样,它也与Connect--一个用于Node的 "插件 "库深深交织在一起。Connect创造了中间件这个术语,用来描述可以在不同程度上处理网络请求的可插入的Node模块。2014年,在4.0版本中,Express取消了对Connect的依赖,但它的中间件概念仍归功于Connect。

Node,一种新型的网络服务器

在某种程度上,Node与其他流行的网络服务器有很多共同之处,如微软的互联网信息服务(IIS)或Apache。不过,更有趣的是它的不同之处,所以让我们从这里开始。

与Express一样,Node对Web服务器的处理方式也是非常简约的。不像IIS或Apache,一个人可以花很多年时间来掌握,Node很容易设置和配置。这并不是说在生产环境中调整Node服务器以获得最大性能是一件小事;只是配置选项更简单、更直接而已。

Node与更传统的网络服务器之间的另一个主要区别是,Node是单线程的。乍一看,这似乎是一种退步。事实证明,这是一个天才之举。单线程极大地简化了编写网络应用的工作,如果你需要多线程应用的性能,你可以简单地旋转更多的Node实例,你将有效地获得多线程的性能优势。精明的读者可能会认为这听起来像烟雾弹。毕竟,通过服务器并行化(相对于应用程序并行化)进行多线程,不就是简单地移动复杂性,而不是消除它?也许吧,但根据我的经验,它恰恰把复杂性移到了它应该在的地方。此外,随着云计算的日益普及和将服务器作为通用商品对待,这种方法更有意义。IIS和Apache确实很强大,它们被设计用来从当今强大的硬件中榨取最后一滴性能。不过,这也是有代价的:它们需要相当多的专业知识来设置和调整,以实现这种性能。

就应用程序的编写方式而言,Node应用程序与PHP或Ruby应用程序有更多共同之处,而不是.NET或Java应用程序。虽然Node使用的JavaScript引擎(谷歌的V8)确实将JavaScript编译为本地机器代码(很像C或C++),但它是透明的,1所以从用户的角度来看,它的行为就像一个纯粹的解释语言。没有单独的编译步骤可以减少维护和部署的麻烦:你所要做的就是更新一个JavaScript文件,你的改动就会自动出现。

Node应用程序的另一个引人注目的好处是,Node是令人难以置信的平台独立。它不是第一个或唯一一个平台独立的服务器技术,但平台独立实际上是一个光谱,而不是一个二元命题。例如,由于Mono的存在,你可以在Linux服务器上运行.NET应用程序,但由于文档不全和系统不兼容,这是个痛苦的尝试。同样地,你可以在Windows服务器上运行PHP应用程序,但通常不像在Linux机器上那样容易设置。另一方面,Node在所有主要的操作系统(Windows、macOS和Linux)上的设置都是轻而易举的,并能实现轻松协作。在网站设计团队中,混合使用PC和Mac是很常见的。某些平台,如.NET,给经常使用Mac的前端开发和设计人员带来了挑战,这对协作和效率有很大影响。能够在几分钟内(甚至几秒钟内!)在任何操作系统上启动一个正常运行的服务器的想法是一个梦想成真。

Node生态系统

当然,Node是这个堆栈的核心。它是使JavaScript在服务器上运行的软件,与浏览器脱钩,这反过来又使用JavaScript编写的框架(如Express)得以使用。另一个重要的组件是数据库,这将在第13章中更深入地介绍。除了最简单的网络应用外,所有的网络应用都需要一个数据库,而且有些数据库比其他数据库更适合在Node生态系统中使用。

所有主要的关系型数据库(MySQL、MariaDB、PostgreSQL、Oracle、SQL Server)都有数据库接口,这并不奇怪;忽视这些成熟的庞然大物是愚蠢的。然而,Node开发的出现使一种新的数据库存储方法重新焕发活力:所谓的NoSQL数据库。将某些东西定义为它不是什么,并不总是有帮助的,所以我们要补充的是,这些NoSQL数据库可能被更恰当地称为 "文档数据库 "或 "键/值对数据库"。它们提供了一种在概念上更简单的数据存储方法。有很多,但MongoDB是排头兵之一,它是我们在本书中要使用的NoSQL数据库。

由于建立一个功能性的网站取决于多种技术,因此产生了一些缩略语来描述一个网站所建立的 "堆栈"。例如,Linux、Apache、MySQL和PHP的组合被称为LAMP栈。MongoDB的工程师Valeri Karpov创造了缩写MEAN:Mongo, Express, Angular, and Node。虽然它确实朗朗上口,但也有局限性:数据库和应用框架的选择太多,"MEAN "并没有捕捉到生态系统的多样性(它也忽略了我认为重要的组成部分:渲染引擎)。

创造一个包容性的缩写是一项有趣的工作。当然,不可缺少的组件是Node。虽然还有其他服务器端的JavaScript容器,但Node正在成为主导。Express也不是唯一的网络应用程序框架,尽管它的主导地位与Node接近。另外两个通常对Web应用开发至关重要的组件是数据库服务器和渲染引擎(要么是像Handlebars这样的模板引擎,要么是像React这样的SPA框架)。对于后两个组件,没有那么多明确的领跑者,而这正是我认为限制性的地方,是一种伤害。

将所有这些技术联系在一起的是JavaScript,所以为了使其具有包容性,我将提及JavaScript栈。在本书中,这意味着Node、Express和MongoDB(第13章中还有一个关系数据库的例子)。

许可证
在开发Node应用程序时,你可能会发现自己比以前更需要注意许可问题(我当然也是如此)。Node生态系统的优点之一是为你提供了大量的包。然而,这些包中的每一个都有自己的许可,更糟糕的是,每一个包都可能依赖于其他的包,这意味着了解你所写的应用程序的各个部分的许可可能是很棘手的。

不过,也有一些好消息。Node包最受欢迎的许可之一是MIT许可,它是无痛的许可,允许你做几乎任何你想做的事情,包括在闭源软件中使用该包。然而,你不应该只是假设你使用的每个包都是MIT许可的。

小贴士
npm中有几个包可以尝试找出你项目中每个依赖关系的许可证。在npm中搜索nlf或license-report。

虽然MIT是你最常遇到的许可证,但你也可能看到以下许可证。

GNU通用公共许可证(GPL)
GPL是一个流行的开源许可证,它被巧妙地设计为保持软件的自由。这意味着如果你在你的项目中使用GPL许可的代码,你的项目也必须是GPL许可。自然,这意味着你的项目不能是闭源的。

阿帕奇2.0
这个许可证,像MIT一样,允许你为你的项目使用不同的许可证,包括闭源许可证。然而,你必须包括使用Apache 2.0许可证的组件的通知。

伯克利软件发行(BSD)
与Apache类似,这个许可证允许你为你的项目使用任何你想要的许可证,只要你包括BSD许可证的组件的通知。

注意
软件有时是双重许可的(在两个不同的许可下许可)。这样做的一个常见原因是允许该软件同时用于GPL项目和具有更宽松许可的项目。(如果一个组件要用于GPL软件,该组件必须是GPL许可的)。这是我在自己的项目中经常采用的一种许可方案:GPL和MIT的双重许可。

最后,如果你发现自己在编写自己的软件包,你应该成为一个好公民,为你的软件包选择一个许可证,并正确地记录下来。对于一个开发者来说,没有什么比使用别人的包而不得不在源代码中挖掘以确定许可,或者更糟的是,发现它根本没有许可更令人沮丧的了。

总结
我希望这一章能让你更深入地了解什么是Express,以及它是如何融入更大的Node和JavaScript生态系统的,并对服务器端和客户端Web应用程序之间的关系有一些清晰的认识。

如果你仍然对Express是什么感到困惑,不要担心:有时开始使用某种东西来理解它是什么要容易得多,本书将让你开始用Express构建Web应用程序。不过,在开始使用Express之前,我们将在下一章对Node进行考察,这是理解Express工作原理的重要背景信息。