Node学习指南(第2版)(txt+pdf+epub+mobi电子书下载)


发布时间:2020-08-17 05:39:00

点击下载

作者:(美) 谢利·鲍尔斯(Shelley Powers)

出版社:人民邮电出版社有限公司

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

Node学习指南(第2版)

Node学习指南(第2版)试读:

前言

Node.js的出现已经有一段时间了,而且已经被很多大公司(LinkedIn、Yahoo!和Netflix)使用,但它仍然很年轻,以至于很多公司的中层管理人员在进行决策时对它存有疑虑。它的成功促使我们去创造一种更为复杂的JavaScript,也让我们可以没有后顾之忧地使用新的语言特性。反过来,最新版的JavaScript也推动了Node.js的组织改革和发布规范的设立。

Node.js重新定义了我们能用JavaScript干什么。现在,雇主不但要求JavaScript程序员能在我们所熟知的浏览器端进行开发,也要求他们能进行服务端开发。另外,Node.js创造了一种新的服务端语言,这种新的语言正在不断吸引着Ruby、C++、Java和PHP的服务端开发人员(尤其是其中一些会JavaScript的开发人员)。

我觉得Node.js很有趣。因为相对于很多其他环境而言,它的门槛很低,很容易创建和运行应用,用它尝试新想法也比较容易。Node项目所需要的环境配置比其他语言要简单和直观一些。只有PHP的环境配置的简单程度可以媲美Node,但即便如此,PHP还是需要和Apache结合起来,才能创建出对外可用的应用。

虽然听着简单,但Node.js也有复杂的地方。学习Node.js意味着你需要学习如何配置环境、掌握核心API,但同时,发现并掌握其复杂的一面也很重要。本书所面向的读者

我觉得本书的受众有两种人。

第一种是已经使用过各种库和框架搭建前端应用,现在想要将自己的JavaScript知识扩展到服务端的开发人员。

第二种是想要尝试新鲜事物,或者学习新技术的后端开发人员。这些开发人员从事过Java、C++、Ruby或者PHP的开发工作,但现在他们想要把时不时接触过的JavaScript知识体系化,并和已知的服务端知识结合起来。

这两种看似没有交集的读者有一个共同点,就是都使用JavaScript,或者可以更准确地称为ECMAScript。本书也确实要求读者对JavaScript比较熟悉。这两种读者的另外一个共同点是:都必须学习同样的Node基础知识,包括Node核心API。

然而,不同的读者,因为拥有不同的视角、不同的技能,所以学习体验也会不尽相同。为了协调一致,我会在本书从不同的视角进行讲解。比如说,一个C++或者Java程序员可能会有兴趣创建C++的Node插件,而这对于前端开发者来说可能没多少吸引力。同样,一些类似于“大端”(big-endian)的概念可能对后端开发者来说很熟悉,而对前端开发者来说可能是一头雾水。我没办法从每一种视角进行过于深入的讲解,但我会确保所有的读者都不会看不懂,或者感觉乏味。

有一件事我绝对不会做,就是强迫读者死记硬背。我们会讲到核心模块API,但是我不会逐个讲解其中的对象和函数,因为它们在Node网站上都有文档。相对而言,我会挑选每个模块中的重要方面进行讲解,或者针对Node中一些特定的重要功能进行讲解,从而给读者提供一个可以和其他Node开发人员进行交流的基础。当然了,熟能生巧,而且本书只是一个学习工具。读完本书之后,读者还需要继续对Node进行深入的探索,比如在Mongo-Express-Angular-Node(MEAN)技术栈上工作。Node中有很多方向可以选择,本书将会为读者提供一些建议。聊聊Node文档  写作本书之时,我和其他一些Node开发者正在进行一个关于Node.js网站现存问题的讨论,其中一点就是关于如何定义Node.js的“当前”版本,也就是说,当用户访问“这个”文档时,应该显示什么样的版本。我最后一次参与这个讨论的时候,大家的计划是在/docs页面列出Node.js的所有当前的长期维护(LTS)版本,还要列出当前的稳定版本,同时要在页面顶端显示出当前文档的版本号。最终,文档的维护人员想要针对每个页面生成一个版本差异(version diffs),但这将会是一个艰巨的任务。本书出版之时,Node发布了6.0.0版本,它是当前版本,并且它不再将活跃开发分支称为稳定版(Stable)。因此,Node.js 6.0.x最终将被转至下一个LTS版本。因为Node的版本如此之多,所以每当你访问Node API的文档网站时,一定要检查文档版本与你使用的Node版本是否一致。当然,查看一下新版文档中的新功能也没什么坏处。

  Node.js就是Node 官方名称Node.js实际上极少被人使用,所有人都称之为“Node”。本书中绝大部分地方也会使用Node来指代Node.js。本书结构

本书着重于基础,重点讲解Node和组成Node核心的一些模块,我也会稍微涉及一些第三方模块,并把npm作为扩展知识来讲解,但是本书最重要的目标还是为读者讲解Node的基础功能。有了这些基础知识,读者就可以在不同方向进行深入研究。

第1章主要是对Node的介绍,其中有一节介绍了如何安装Node。读者还可以对Node进行一些探索,包括使用Node文档中的代码创建一个Web服务器,接着使用我提供的代码创建一个稍微高级一点儿的Web服务器。我也会为读者中的C/C++程序员讲解如何创建Node插件。另外,讲解Node怎么能抛开它的历史不谈呢?更别说Node的历史还真是与众不同,因为它跳过了1.0版本,直接发布了4.0版本。

第2章主要讲解Node的核心功能,包括如何处理事件,以及各种功能赖以生存的global对象,还有Node的异步特性。另外,我还会讲解缓冲器(buffer)对象,也就是Node里用来在网络服务中进行数据传输的数据结构。

第3章会深入讲解Node的模块系统,包括深入研究npm——Node的一个第三方模块管理系统。这一章中,读者将会学习到如何将自己的应用与Node模块集成,以及如何创建自己的Node模块。最后,我会讲解Node功能中一个稍微高级点的内容——沙箱(sandboxing)。同时,为了让学习更有趣,我会介绍3个流行的Node第三方模块:Async、Commander和Underscore。

在第4章中,我会用整章的篇幅来讲解一个很有价值的学习工具,Node的互动式控制台——REPL,其本身也是一个开发环境。我会详细讲解如何使用这个工具,还会介绍如何创建自己的REPL。

在第5章,我们会探索Node的Web应用,包括去了解有哪些Node模块支持了Web开发。在这一章,读者可以学习如何构建一个功能完整的Web服务器,以及如何使用Apache代理将Node应用和Apache一起运行。

Node可以在多种环境下运行,如Windows,基于UNIX的OS X,还有Linux。这是因为Node提供了一系列可以屏蔽系统差异的功能,这部分内容我们会在第6章讲到。另外,我还会讲到Node中的流(stream)和管道(pipe)的基础知识。它们是一切输入输出的核心,另外本章还会介绍Node对文件系统的支持。

第7章全部是关于网络的。说到网络,就不能不涉及安全。这两部分内容总是会同时出现。我会介绍Node对TCP和UDP的支持,以及如何实现一个HTTPS服务器,这作为第5章学习实现HTTP服务器的补充。另外我还会介绍数字证书背后的机制,以及SSL(Secure Sockets Layer,安全套接层)的基础,还有它的升级版TLS(Transport Layer Security,传输层安全)。最后,我们会学习Node的加密模块,以及如何为密码加密。

我最喜欢的Node的功能之一,就是它可以通过子进程(child process)来调用系统功能。很多我喜欢的小型工具类应用,比如用来压缩文件的应用、图形处理应用(如ImageMagick)、从网站截图的应用,都不是特别大型的应用,无须复杂的云接口,但却是学习子进程的绝佳方式。我们会在第8章介绍子进程。

本书中大部分的示例代码,都是用大家熟知的JavaScript编写的。但是,Node.js和io.js分离又合并的原因,就在于对新版ECMAScript(比如ES6或者ECMAScript 2015)的支持。在第9章中,我会介绍当前Node版本所支持的功能、新功能的影响,以及什么时候应该用新功能取代旧功能。我还会介绍在使用JavaScript新功能时的一些陷阱。另外,我会讲解Bluebird的promise功能,这是本书中唯一一个脱离Node原生功能的部分。

第10章会讲解全栈Node编程(full-stack Node developement)所涉及的框架和功能。我会讲到Express—— 一个被普遍使用的Node组件,还会讲到MongoDB和Redis。我们还会学习组成全栈开发的另外两个框架:AngularJS和Backbone.js。

编程结束之后,你可能会想把自己的代码发布到产品环境中,第11章讲解了一些在开发环境和产品环境中需要用到的工具和技术,包括单元测试、负载测试和基准测试,以及一些基本的调试技术和工具。读者还会学到如何保证程序持续运行,以及如何在程序崩溃时自动重启。

第12章属于“饭后甜点”。在这一章,我会指引读者将已有的Node知识用于新的世界,包括属于物联网的微控制器和微计算机,以及一个并不运行在V8引擎上的新版本Node。本书约定

本书中使用了以下字体作为约定内容。

等宽字体(constant width)

用于表示对代码的指代和段落内对程序元素的指代,比如变量名、函数名、数据库、数据类型、环境变量、声明和关键字。粗体(bold)

用于表示用户应该手动输入的命令或者文本。

等宽斜体(Constant width italic)

表示用户应该使用自己的内容或者上下文相关的内容来替代等宽斜体文字。 这个图片表示一个提示或者建议。

  这个图片表示一个一般说明。

  这个图片表示一个警告或者注意事项。代码示例的使用

本书的目的是为了帮助读者完成工作。一般而言,读者可以在自己的程序和文档中使用本书中的代码,而且也没有必要取得我们的许可。但是,如果要复制的是核心代码,则需要和我们打个招呼。例如,可以在无须获取我们许可的情况下,在程序中使用本书中的多个代码块。但是,销售或分发O’Reilly图书中的代码光盘则需要取得我们的许可。通过引用本书中的示例代码来回答问题时,不需要事先获得我们的许可。但是,如果产品文档中融合了本书中的大量示例代码,则需要取得我们的许可。

在引用本书中的代码示例时,如果能列出本书的属性信息是最好不过了。一个属性信息通常包括书名、作者、出版社和ISBN。例如:“learning Node, Second Edition, by Shelley Powers (O’Reilly). Copyright 2016 Shelley Powers, 978-1-491-94312-0.”

在使用书中的代码时,如果不确定是否属于正常使用,或是否超出了我们的许可,请通过permissions@oreilly.com与我们联系。联系方式

如果你想就本书发表评论或有任何疑问,敬请联系出版社。

美国:

O’Reilly Media Inc.

1005 Gravenstein Highway North

Sebastopol, CA 95472

中国:

北京市西城区西直门南大街2号成铭大厦C座807室(100035)

奥莱利技术咨询(北京)有限公司®Safari 在线图书

Safari在线图书是一个按需订阅的数字图书馆。它至少有7 500本与技术和创意相关的图书和视频供你参考和搜索。

通过订阅,你可以在线阅读所有的页面和视频,甚至可以在手机或移动设备上在线阅读。你可以在图书出版前访问到它们,并给作者发送反馈。其他功能还包括:复制和粘贴代码、组织收藏夹、下载和标记章节、做笔记、打印等。

O’Reilly Media已经将本书的英文版上传到Safari在线图书服务。在safari官网上免费注册,你就可以访问本书所有章节以及类似主题的图书。致谢

我要感谢帮助我写作此书的人:编辑,Meg Foley;技术评论人,Ethan Brown;文字编辑,Gillian McGarvey;校对人,Rachel Monaghan;索引人,Judy McConville;插画师,Rebecca Panzer;以及其他所有接触过此书的人!资源与支持

本书由异步社区出品,社区(https://www.epubit.com/)为您提供相关资源和后续服务。配套资源

本书提供如下资源:● 书中彩图文件。

要获得以上配套资源,请在异步社区本书页面中点击,跳转到下载界面,按提示进行操作即可。注意:为保证购书读者的权益,该操作会给出相关提示,要求输入提取码进行验证。提交勘误

作者和编辑尽最大努力来确保书中内容的准确性,但难免会存在疏漏。欢迎您将发现的问题反馈给我们,帮助我们提升图书的质量。

当您发现错误时,请登录异步社区,按书名搜索,进入本书页面,点击“提交勘误”,输入勘误信息,点击“提交”按钮即可。本书的作者和编辑会对您提交的勘误进行审核,确认并接受后,您将获赠异步社区的100积分。积分可用于在异步社区兑换优惠券、样书或奖品。与我们联系

我们的联系邮箱是contact@epubit.com.cn。

如果您对本书有任何疑问或建议,请您发邮件给我们,并请在邮件标题中注明本书书名,以便我们更高效地做出反馈。

如果您有兴趣出版图书、录制教学视频,或者参与图书翻译、技术审校等工作,可以发邮件给我们;有意出版图书的作者也可以到异步社区在线提交投稿(直接访问www.epubit.com/selfpublish/submission即可)。

如果您是学校、培训机构或企业,想批量购买本书或异步社区出版的其他图书,也可以发邮件给我们。

如果您在网上发现有针对异步社区出品图书的各种形式的盗版行为,包括对图书全部或部分内容的非授权传播,请您将怀疑有侵权行为的链接发邮件给我们。您的这一举动是对作者权益的保护,也是我们持续为您提供有价值的内容的动力之源。关于异步社区和异步图书“异步社区”是人民邮电出版社旗下IT专业图书社区,致力于出版精品IT技术图书和相关学习产品,为作译者提供优质出版服务。异步社区创办于2015年8月,提供大量精品IT技术图书和电子书,以及高品质技术文章和视频课程。更多详情请访问异步社区官网https://www.epubit.com。“异步图书”是由异步社区编辑团队策划出版的精品IT专业图书的品牌,依托于人民邮电出版社近30年的计算机图书出版积累和专业编辑团队,相关图书在封面上印有异步图书的LOGO。异步图书的出版领域包括软件开发、大数据、AI、测试、前端、网络技术等。异步社区微信服务号第1章 Node运行环境

虽然Node主要被当作服务器端应用程序来使用,但这并不是它唯一的用途。事实上,Node几乎可以被安装在任何机器上,也可以被用来做任何事情,比如它可以在你的计算机、平板电脑、智能手机甚至微型计算机上运行程序。

我在我的Linux服务器、Windows 10系统的计算机和微型计算机(树莓派)上都安装了Node,而且正在考虑给我另外一个Android平板电脑也安装Node,这样我就可以用Node在Arduino Uno微型控制器上编程了。另外,感谢IFTTT的Maker Channel(创造者频道),我可以借助它将Node集成到我的智能家居中。在计算机上,Node可以用来测试JavaScript,也可以作为接口调用ImageMagick来批量处理照片。事实上,不论是计算机还是服务器,Node都是一个可以做任何批处理操作的快捷工具。

当然,当我需要一个后端服务来绕开Apache服务器或者构建一个网站后端的时候,我还是会使用Node来进行服务器端的处理。

综上所述,Node开发环境的功能非常强大,同时也非常容易安装。而开始在Node公园中尽情“玩耍”之前,我们得先买“门票”:安装Node。 IFTTTIFTTT是一个神奇的网站,你可以使用简单的if-then逻辑将公司、服务、产品通过触发器和执行器连接起来。连接的两个终端都叫频道,包括我们之前提到的创造者频道(Maker Channel)。1.1 安装Node

要安装Node,最好从Node.js的下载页面开始。在这里你可以下载到适用于Windows、OS X、SunOS、Linux以及ARM等平台的二进制文件(预编译的可执行文件)。这个页面也提供了个别平台的安装文件,这些安装文件可以大幅简化安装过程——特别是Windows版。如果你本地有编译环境,也可以下载源代码,然后直接编译Node。在我的Ubuntu服务器上,我就是这么做的。

你也可以使用平台对应的安装文件来安装Node,这样不仅方便安装,也方便更新(我们会在1.4节中深入讨论)。

如果你准备直接在本地环境中编译Node,那么必须先设置好本地的编译环境,并且安装合适的编译工具。比如在Ubuntu(Linux)上,就需要运行下面这条命令来安装所需的工具:apt-get install make g++ libssl-dev git

在不同的平台上,第一次安装Node的过程会略有差异。比如,在Windows上安装Node时,安装文件不仅会安装Node,同时也会在本地创建一个用来运行Node的命令窗口。这是因为Node是一个命令行程序,不像典型的Windows程序那样拥有一个图形界面。要想在Arduino Uno上面用Node来编程,那你就需要安装Node和Johnny-Five,然后将二者结合起来对所连接的设备进行编程。 接受Windows世界中的默认设置在Windows上安装Node时,最好接受默认安装路径和安装功能的设置。因为安装文件会将Node加入到PATH环境变量中,之后就可以直接输入node来运行Node,而不用输入整个安装路径。

在树莓派中安装Node时,需要下载对应的ARM版本,比如原版树莓派需要下载ARMv6,新版树莓派2需要下载ARMv7。下载好之后,从压缩包中将二进制文件解压出来,放在/usr/local目录下:wget https://nodejs.org/dist/v4.0.0/node-v4.0.0-linux-armv7l.tar.gztar -xvf node-v4.0.0-linux-armv7l.tar.gzcd node-v4.0.0-linux-armv7lsudo cp -R * /usr/local/

你也可以在本地搭建编译环境,然后直接编译Node。 新的Node环境既然说到了Arduino和树莓派,我会在第12章介绍在一些非传统环境(如物联网)中的Node的使用。1.2 使用Node编写“Hello, World”

刚刚装完Node,你一定想试试吧。程序员的世界里有一个传统,就是学习一门语言时,从“Hello, World”开始。不论输出流是什么,这个程序只输出“Hello, World”这两个单词,借此展示如何创建程序、运行程序,以及如何对输入和输出进行处理。

对Node而言也是如此——在Node.js的网站上,文档的概要部分就包含了“Hello, World”的代码。这也是我们在本书中第一个要写的程序,只不过这里会略作调整。1.2.1 一个基本的Hello World程序

让我们先来看看Node官方文档中的“Hello, World”程序。用你最喜欢的文本编辑器(我在Windows中用notepad++,在Linux中用Vim)创建一个文本文件,然后把下面这段JavaScript代码复制进去。var http = require('http');http.createServer(function (request, response) { response.writeHead(200, {'Content-Type': 'text/plain'}); response.end('Hello World\n');}).listen(8124);console.log('Server running at http://127.0.0.1:8124/');

然后将文件保存为hello.js。要运行这个程序,在OSX或者Linux中需要打开一个终端(terminal),在Windows下则需要打开Node命令行窗口。切换到文件所在的目录,然后输入这行命令就可以运行程序了。node hello.js

程序通过console.log()函数调用将执行结果打印到命令行。Server running at http://127.0.0.1:8124/

然后打开浏览器,在地址栏中输入http://localhost:8124/或者http://127.0.0.1:8124(如果是在自己的服务器上运行这个程序,也可以输入你自己的域名)。此时浏览器中应该显示一个简单朴素的Web页面,页面顶上有“Hello World”字样,如图1-1所示。

如果你是在Windows上面运行这个程序,那你很有可能会收到一个Windows防火墙的警告信息,如图1-2所示。取消公用网络,选择私人网络,然后单击“允许访问”按钮。图1-1 你的第一个Node程序图1-2 在Windows中设置允许访问Node程序

Windows会记住你的选择,所以这个操作做一次就够了。

要退出这个程序,你可以直接关掉终端或者命令行窗口(命令行窗口其实也是终端),也可以按Ctrl-C组合键。因为我们的程序是从终端前台运行的,所以其实除了按Ctrl-C组合键之外,你也没办法输入别的命令,同时关掉终端意味着Node进程也会被关闭。 如何获取稳定的Node运行环境就现在而言,在终端前台运行Node没什么问题。你正在学习如何使用这个工具,但你不希望你的应用程序被其他人使用,而且希望在结束使用的时候可以终止它。我们会在第11章讲到如何创建一个更为稳定的Node运行环境。

回到我们的Hello World程序,JavaScript为我们创建了一个Web服务,我们在浏览器中访问它时,会显示包含“Hello World”的Web页面。在这个例子中我们使用了Node的好几个关键模块。

首先,它包含了运行一个简单的HTTP服务器所必需的模块:一个以HTTP命名的模块。Node的非核心功能是通过不同的模块来引入的。这些模块会对外暴露其特有的功能,这些功能可以被程序或者另外一个模块引用,就像你在其他编程语言中用过的类库一样。var http = require('http'); Node模块、核心模块和HTTP模块HTTP模块是Node的核心模块之一,讲解核心模块是本书的主要内容。我会在第3章深入地讲解Node模块和模块管理,然后在第5章讲解HTTP模块。

这个模块是通过Node的require声明引入的,其结果被赋值到一个局部变量。引入完成之后,我们就可以用这个局部变量来实例化Web服务,即http.createServer()函数。在函数的参数中,我们用到了回调函数(见例1-1),这是构成Node的基本概念之一。匿名函数会把Web端的请求(request)和响应(response)传递给对应的代码,如此一来就可以方便地处理请求并生成对应的响应了。

例1-1 Hello World回调函数http.createServer(function (request, response) { response.writeHead(200, {'Content-Type': 'text/plain'}); response.end('Hello World\n'); }).listen(8124);

JavaScript是单线程的。那么Node是如何在单线程环境下模拟一个异步环境的呢?答案是事件循环(event loop),也就是通过在特定事件被触发时,调用相关的回调函数来完成。在例 1-1中,只要接收到一个Web请求,回调函数就会被执行。

创建Web服务的函数调用完成之后,console.log()会将消息打印到终端中。此时程序本身并不会结束或是阻塞,而是在等待接受Web请求。console.log('Server running at http://127.0.0.1:8124/'); 关于事件循环和回调函数我会在第2章中讲解更多关于Node事件循环、它对异步编程的支持以及回调函数的内容。

Web服务被创建,并且接收到一个Web请求之后,回调函数就会向浏览器发送一个纯文本的响应头(response header)和200的状态码(status code),然后发送Hello World这段信息,最后结束响应。

恭喜!你通过短短几行代码就用Node创建了第一个Web服务。但是,这远远不够,除非你唯一的兴趣就是向世界问好(Hello World!)。在本书中你将会学习如何写出更有用的Node程序,但是在结束Hello World的练习之前,让我们在这个基本程序上面做一点修改,让它变得更有意思。1.2.2 升级版Hello World

上面的程序成功打印了一段静态文本,这说明:第一,程序是可以正常工作的;第二,它向我们展示了如何创建一个简单的Web服务。这个最基本的例子也展示了Node程序的几个关键元素。但是如果把它稍微丰富一下,它就会变得更有趣。我做了一点升级,写了第二个程序,加入了一些可变因素。

升级后的代码如例1-2所示。在新的代码中,我对传入的Web请求进行解析,然后查找一个参数,将参数中的名字(name)取出来,以便确定响应的内容。几乎所有的name都会有一个个性化的响应,除非你在参数中加入name=burningbird,此时服务器端将会返回一张图片。如果name参数没有被指定,那name参数就被设为“world”。

例1-2 升级版Hello Worldvar http = require('http');var fs = require('fs');http.createServer(function (req, res) { var name = require('url').parse(req.url, true).query.name; if (name === undefined) name = 'world'; if (name == 'burningbird') { var file = 'phoenix5a.png'; fs.stat(file, function (err, stat) { if (err) { console.error(err); res.writeHead(200, {'Content-Type': 'text/plain'}); res.end("Sorry, Burningbird isn't around right now \n"); } else { var img = fs.readFileSync(file); res.contentType = 'image/png'; res.contentLength = stat.size; res.end(img, 'binary'); } }); } else { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello ' + name + '\n'); }}).listen(8124);console.log('Server running at port 8124/');

使用?name=burningbird作为参数来访问我们的Web应用,将会得到下面的图片,如图1-3所示。图1-3 Hello, Burningbird

升级后的Hello World程序并没有比原版增加多少代码,但还是有些区别。一开始,程序中就引入了一个名叫fs的新模块,即文件系统模块。在未来的几章里,你将对这个模块非常熟悉。另外还有一个模块,它的引入方式就不太一样了:var name = require('url').parse(req.url, true).query.name;

模块暴露的属性可以被链式调用,因此我们可以把模块的引入和模块中方法的调用放在同一行。我们通常会在使用URL这个模块的时候用到这种方式,这个模块就是一个URL的工具集。

response和request参数的变量名可以缩写为res和req,以便于日后使用。当我们解析完request,就得到了name的值,首先检测一下这个值是不是undefined。如果是,这个值就会被赋值为默认值world;而如果name不是undefined,我们会再检测它是否等于burningbird。如果不等于,那么程序的结果和我们在初级版程序中看到的很像,只不过返回的字符串中加入了我们提供的名字。

但是,如果name等于burningbird,我们就需要处理一张图片,而不是一段文字了。fs.stat()方法不但会验证文件是否存在,而且也会返回一个包含文件信息的对象,包括它的大小。这个值会被用来创建响应内容的头(content header)。

如果文件不存在,程序也会很优雅地处理这个情况:它会展示出一个友好的信息,告诉你这只鸟已经从笼子里飞走了,同时也会使用console.error()方法在控制台输出错误信息:{ [Error: ENOENT: no such file or directory, stat 'phoenix5a.png'] errno: -2, code: 'ENOENT', syscall: 'stat', path: 'phoenix5a.png' }

如果文件存在,那么我们就将图片读取出来并赋值给一个变量,然后在响应中返回,同时相应地调整头(header)的值。

fs.stats()方法使用标准的Node回调函数模式,即把错误值作为第一个参数——通常被称为errback。但是,读取图片部分的代码可能会让你搞不清楚。它看起来有点奇怪,和你在本章中看到的其他Node函数不太一样(很可能跟你在其他在线示例中看到的也不一样)。它的不同之处在于,我使用了一个同步函数readFileSync(),而不是它的异步版本readFile ()。

对于大多数文件系统功能,Node同时提供同步和异步两个版本的函数。通常,在Node中的Web请求中使用同步操作是一种忌讳,但是Node确实提供了这样的功能。例1-3是同样一段代码的异步实现。

例1-3fs.readFile(file, function(err,data) { res.contentType = 'image/png'; res.contentLength = stat.size; res.end(data, 'binary'); });

那什么时候应该用同步函数,什么时候又该用异步函数呢?在某些情况下,无论你使用哪种类型的函数,文件I/O都不会影响性能,同步函数可以让代码干净,也更易于使用。它还可以减少代码嵌套——代码嵌套是Node回调系统的一个特殊问题,我将在第2章更详细地介绍。

此外,虽然我没有在例子中使用异常处理,但是你可以将try … catch与同步函数结合使用。你不能将这种传统的错误处理方式与异步函数结合使用(因为匿名回调函数的第一个参数就是错误值)。

所以从第二个例子中,我们学到的重点是,Node中的I/O并不都是异步的。 文件系统和URL模块,缓冲器(buffer)以及异步I/O我将在第5章更详细地介绍URL模块,在第6章讲解文件系统。但是请注意,文件系统的使用会贯穿整本书。缓冲器和异步处理的内容会在第2章中介绍。1.2.3 Node命令行参数

在前面两节中,Node都是在命令行中调用的,而且不带任何参数。在继续下面的内容之前,我想简要介绍一些命令行参数。其他的参数会在需要时再介绍。

使用help参数(-h或--help),可以展示出所有可以使用的选项和参数:$ node --help

这个参数会列出Node的所有参数,同时展示使用语法:Usage: node [options] [ -e script | script.js ] [arguments] node debug script.js [arguments]

要知道Node的版本信息,可以使用下面这个命令:$ node -v or –-version

要查看某个Node应用的语法,可以使用-c参数。这个参数可以在不运行应用的情况下查看运行语法:$ node -c or --check script.js

要查看V8参数,请输入:$ node --v8-options

这个命令会返回几个不同的参数,包括--harmony参数。这个参数用于开启所有已完成的Harmony JavaScript功能。这包括已经实现但尚未纳入LTS或当前Node版本的所有ES6功能。

我最喜欢的Node参数是-p或--print,它可以运行一行Node脚本并打印结果。如果你正在使用进程的环境变量(我们将在第2章进行更全面的讨论),那么这一参数将尤其有用。下面是一个例子,这个例子会打印出process.env属性的所有值:$ node -p "process.env"1.3 Node部署环境

学习Node时,你可能更想在自己的本地环境中熟悉它,无论是Windows、OS X还是Linux。当你想让更多的人访问你的程序时,你将需要:找到一个可以运行Node程序的环境,例如我自己正在使用的虚拟专用网络(VPN),或者一个可以提供Node支持的主机。前者要求你在运行一个面向互联网的服务器方面具有一定经验,而后者可能会限制你所使用的Node程序的权限。1.3.1 将Node部署在你的服务器、VPS或者托管主机上

把Node应用部署在和WordPress一样的机器上是行不通的,因为Node有特殊的权限需求。虽然没有root或管理权限也可以运行Node,但最好有。此外,许多托管公司并不喜欢让你在多个端口上托管(host)应用,不论它会不会对其系统造成破坏。

在虚拟专用服务器(VPS)(例如我在Linode上的VPN)上部署Node,是一件很简单的事情。你的VPS具有root访问权限,只要你不危及可能位于同一机器上的其他用户,就可以做任何操作。提供VPS的大多数公司都能确保每个个人账户与其他账户隔离,也没有任何一个账户能够占用所有可用的资源。

但是,使用VPS的问题与你使用自己的服务器时所遇到的问题相同:你必须维护服务器,包括设置电子邮件系统和别的Web服务器——通常是Apache或Nginx——来处理防火墙、其他安全性问题以及电子邮件等。这可不是小问题。

不过,如果你有能力全面地管理一个互联网主机,VPS足以用来部署Node程序了。在你准备好将程序部署到产品环境之前,你可能会想要了解一下如何在云端环境部署应用程序。1.3.2 云部署

如今,一个应用程序运行于云服务器,和运行在个人或群组计算机上一样常见。Node程序非常适合基于云端的实现方式。

当你在云上部署Node应用程序时,你通常需要在自己的服务器或PC上创建应用程序,进行测试,确保它一切正常,然后将应用程序推送到云服务器。Node的云服务器允许你使用任何数据库系统或其他系统的资源创建Node应用程序,但无须直接管理服务器。你可以专注于Node应用程序,而无须担心FTP、电子邮件服务器或一般服务器的维护。Git和GitHub:Node部署的前提如果你从未使用过Git源码控制系统,则需要将其安装到你的环境中并学习如何使用它。几乎所有Node应用程序的转换,包括将应用程序推送到云服务器,都是通过Git进行的。Git是开源和免费的,并且易于安装。你可以通过访问Git网站来获取这个软件。在GitHub上还有一个互动指南,可以用来学习基本的Git命令。说到Git,哪里有Git,哪里就有GitHub。Node.js的源代码就是维护在GitHub上的,大部分(也可能是全部)可用的Node模块也是一样。本书例子的源代码也可以在GitHub上找到。GitHub可能是世界上最大的开源代码库。它绝对是Node世界的中心。它是一个商业化公司,但对大多数用户来说都是免费的。GitHub提供了很好的文档,帮助用户了解如何使用该网站。还有一些书籍和其他教程,可以帮你更快上手Git和GitHub。其中包括一本免费的Git电子书、Loeliger和McCullough的《Git版本控制》(O’Reilly)以及Bell和Beer的《GitHub入门》(O’Reilly)。

在云服务上托管Node应用程序的流程,对于所有云服务来说都非常相似。首先,在本地或在自己的服务器上创建Node应用程序。当你准备开始测试部署环境时,就需要寻找一个云服务了。我熟悉的云服务大多会要求你注册一个账户,创建一个新项目,如果云服务提供很多种托管软件环境的话,你还可以指定一个基于Node的环境。需要的话,你还可以指定一些其他资源,例如数据库访问。

一旦准备好部署,你就需要把应用程序推送到云上。你可以使用Git来推送应用程序,也可能需要使用云服务商提供的工具。举个例子,微软Azure云利用Git将应用程序从本地环境推送到云端,而Google的Cloud Platform则提供了一个工具来提供相同的功能。 寻找合适的托管服务虽然可能有些过时,但是刚开始寻找合适的Node托管服务的时候,可以去看看GitHub的相关页面。1.4 Node长期支持和Node升级

2014年,一组Node维护人员分离出来并形成了自己的Node.js分支,名为io.js。当时震惊了Node界(或至少有一些人大吃一惊)。分裂的原因是创建io.js的人觉得,一直对Node进行维护的公司Joyent在实现对Node的监管上步伐太慢。他们还认为Joyent在支持最新的V8引擎更新方面已经落后了。

幸运的是,两个组织已经解决了导致分裂的问题,并将他们的努力重新合并为一个仍然被命名为Node.js的产品。Node现在通过由Linux基金会赞助的管理性非营利组织Node基金会进行管理。因此,两个组织的代码合并起来,不再是第一个官方发布版本Node 1.0,而是Node 4.0。Node 4.0代表了缓慢节奏的Node 1.0和迅猛发展的io.js 3.0版本。1.4.1 Node的最新语义化版本规范

合并的一个结果是,Node开始基于严格的时间线来进行发布,同时版本号遵循语义化版本规范(Semver)。Semver使用3组数字来定义功能发布,每组数字都具有特定含义。例如,写这部分内容时,我在服务器上正在使用的Node.js的版本是4.3.2。这意味着:● 主版本号是4,只有在对Node进行重要的且不向后兼容的更改

时,这个数字才会增加;● 次版本号是3,当有新的功能被添加,但是保持向后兼容时,这

个数字会增加;● 修订号是2,当修复安全性问题或者bug,需要发布一个新版的

时候,会增加这个数字,这个版本号的变化同样是向后兼容的。

我在Windows上使用5.7.1的稳定版本,而在Linux上使用6.0.0版进行测试。

Node基金会还支持另外一种发布方式,比我们熟悉的这种略显随意的发布方式更具稳定性,尽管它存在一些问题。它开始于Node.js v4的第一个LTS(长期支持)版本,一直到2018年4月之前都会获得支持。Node基金会于2015年10月底发布了第一个稳定版本Node.js v5。Node 5.xx只被支持到2016年4月,2016年4月它被Node.js v6替代。该策略是为了每6个月推出一个稳定新版(目前的最新版就是这个版本),但隔一个版本才会有一个LTS,比如Node v4。 6.0.0版作为当前版本发布2016年4月,Node发布了6.0.0版本,取代了5.x版本,并在2016年10月转换为新的LTS。Node还将正在开发的版本从“稳定版”更名为“当前版”。

在2018年4月后,Node v4会进入维护模式。同时,将会出现新的向后兼容更新(称为semver-major bumps,主版本调整),以及安全性问题和bug修复。 本书涵盖哪个版本本书涵盖了Node.js v4的LTS版本。在需要的地方,我会用注释标记出v4和v5/v6之间的差异。

无论你决定使用哪个LTS版本,每个新的安全性/bug修复发布之后,你都需要立即升级。然而,处理主版本更新则取决于你和/或你的组织。升级应该是向后兼容的,仅影响底层引擎的改进。不过,在升级和制定测试计划时,你还是需要将所有新版本都考虑进去。

你应该使用哪个版本呢?在企业或企业环境中,你很可能希望使用LTS版本,目前来说也就是Node.js v4。但是,如果你的环境能够更快地适应突破性变化,则可以使用最新的“Node当前版”以得到最新的v8和其他新特性。 测试和产品中的乐趣我将在第11章讲解Node调试和测试,以及其他一些开发过程和产品程序。1.4.2 Node版本更新

随着发布计划的增加,使Node版本保持最新版尤为重要。幸运的是,升级过程毫不费劲,而且还有替代方案。

你可以通过下面这条命令来检查Node版本:node -v

如果你用的是一个包安装软件,那么运行包更新程序就可以更新Node了,这同时也会更新你的服务器上的其他程序(Windows上不需要sudo):sudo apt-get updatesudo apt-get upgrade --show-upgraded

如果你用的是安装软件,那么请遵循Node网站上提供的相关说明,否则你可能无法更新Node。

你也可以使用npm来更新Node,命令如下:sudo npm cache clean -fsudo npm install -gsudo n stable

如果要在Windows、OS X或者你的树莓派上安装最新版Node,请在Node网站的下载页面中下载安装程序,并且运行。它会用新版覆盖旧版。 Node版本管理器在Linux或者OS X环境中,你也可以使用Node版本管理器(Node Version Manager, nvm)工具来更新Node。

Node包管理器(Node package manager, npm)本身的更新频率甚至比Node还高。要更新npm,只需执行:sudo npm install npm -g n

这个命令将会安装所有需要的软件的最新版。你可以通过这条命令检查npm的版本:npm -v

请注意,这可能会导致某些问题,尤其是在团队环境中。如果你的团队成员使用的Node是用npm安装的,而你手动将npm升级到更新的版本,那么可能出现不一致的构建结果,而且这个问题不易被发现。

我将在第3章更详细地介绍npm,但现在请先记住,你可以使用以下命令将所有Node模块更新到最新版本:sudo npm update -g1.5 Node、V8和ES6

Node背后有一套JavaScript引擎。大多数JavaScript的实现使用的引擎是V8。V8最初是由Google为Chrome开发的,在2008年开源了。V8引擎是为了提高JavaScript的运行速度而创建的,它使用一个即时编译器(JIT)将JavaScript编译成机器代码而不是翻译它(多年来,JavaScript一直是这样被执行的)。V8引擎是用C++编写的。 微软的Node.js分支Microsoft为Node创建了一个分支,以创建一个专门为物联网(IoT)设计的JavaScript引擎(名为Chakra)版本。我将在第12章中详细地介绍这个分支。

Node v4.0发布的时候支持了V8 4.5(也就是Chrome所使用的引擎版本)。Node维护者也一直致力于在每个新版V8发布后提供支持。这意味着Node现在支持许多新的ECMA-262功能(也称为ECMAScript 2015或ES6)。 Node v6的V8支持Node v6支持V8 5.0版本,而未来的Node版本也会支持对应的新版V8。

在旧版Node中,要使用ES6的新特性,你需要在运行程序时加上harmony参数(--harmony):node --harmony app.js

现在,ES6新特性的支持基于以下几个标准(引用自Node.js文档)。● 所有V8认为稳定的已交付功能,在Node.js中都可以直接使用,

不需要任何运行时的参数。● 待交付功能,也就是已经开发完毕,但是V8团队认为还不够稳

定的功能,需要一个运行时参数:--es_staging(或者它的同义

词--harmony)。● 开发中的功能可以使用每个功能对应的参数来开启(如--

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载