深入浅出Node.js[试读]
1.1 Node的诞生历程
Node应该是如今最火热的技术了,从本章开始,我们将逐步揭示它的诸多细节。 1.1 Node的诞生历程 Node的诞生历程如下所示。 2009年3月,Ryan Dahl在其博客上宣布准备基于V8创建一个轻量级的Web服务器并提供一套库。 2009年5月,Ryan Dahl在GitHub上发布了最初的版本。 2009年12月和2010年4月,两届JSConf大会都安排了Node的讲座。 2010年年底,Node获得硅谷云计算服务商Joyent公司的资助,其创始人Ryan Dahl加入Joyent公司全职负责Node的发展。 2011年7月,Node在微软的支持下发布了其Windo... 查看全部[ 1.1 Node的诞生历程 ]
1.2 Node的命名与起源
在Node的官方网站(http://nodejs.org)之外,Node具有很多别称:Nodejs、NodeJS、Node.js等。本书在写作过程中遵循官方的说法,将会一直使用Node这个名字,但是在当前语境之外,为了与其余表示节点的技术或名词相区别,均可以带上.js表明它是Node。在听到这些词汇时,应该意识到,它们说的是一码事。除了本书的封面和此处会用到Node.js外,其余地方都会以Node作为正式称谓。 Node名字的来由,其实跟它的起源是有密切关系的。 1.2.1 为什么是JavaScript Ryan Dahl是一名资深的C/C++程序员,在创造出Node之前,他的主要工作都... 查看全部[ 1.2 Node的命名与起源 ]
1.3 Node给JavaScript带来的意义
V8给Chrome浏览器带来了一个强劲的心脏,使得它在浏览器大战中脱颖而出,也使得Ryan Dahl在语言评估中为选择JavaScript增加了一个极大的权重值。这里我们要谈谈Node给JavaScript带来的一个新局面。鉴于Node之前那些不给力的后端JavaScript实现,在性能和编程模型等方面没能达到与其他语言一较高下的程度,这里先撇开不谈,先谈谈Node与浏览器的对比。 Chrome浏览器和Node的组件构成如图1-1所示。我们知道浏览器中除了V8作为JavaScript引擎外,还有一个WebKit布局引擎。 HTML5在发展过程中定义了更多更丰富的API。在实现上,浏览器提供了... 查看全部[ 1.3 Node给JavaScript带来的意义 ]
1.4 Node的特点
作为后端JavaScript的运行平台,Node保留了前端浏览器JavaScript中那些熟悉的接口,没有改写语言本身的任何特性,依旧基于作用域和原型链,区别在于它将前端中广泛运用的思想迁移到了服务器端。下面我们来看看Node相较其他语言的一些特点。 1.4.1 异步I/O 关于异步I/O,向前端工程师解释起来或许会容易一些,因为发起Ajax调用对于前端工程师而言是再熟悉不过的场景了。下面的代码用于发起一个Ajax请求: $.post('/url', {title: '深入浅出Node.js'}, function (data) { console.log('收到响应'); })... 查看全部[ 1.4 Node的特点 ]
1.5 Node的应用场景
在进行技术选型之前,需要了解一项新技术具体适合什么样的场景,毕竟合适的技术用在合适的场景可以起到意想不到的效果。关于Node,探讨得较多的主要有I/O密集型和CPU密集型。 1.5.1 I/O密集型 在Node的推广过程中,无数次有人问起Node的应用场景是什么。如果将所有的脚本语言拿到一处来评判,那么从单线程的角度来说,Node处理I/O的能力是值得竖起拇指称赞的。通常,说Node擅长I/O密集型的应用场景基本上是没人反对的。Node面向网络且擅长并行I/O,能够有效地组织起更多的硬件资源,从而提供更多好的服务。 I/O密集的优势主要在于Node利用事件循环的处理能力,而不是启动每一个... 查看全部[ 1.5 Node的应用场景 ]
1.6 Node的使用者
在短短四年多的时间里,Node变得非常热门,使用者也非常多。这些使用者对于Node的各自倚重点也各不相同。经过整理,主要有下面几类。 前后端编程语言环境统一。这类倚重点的代表是雅虎。雅虎开放了Cocktail框架,利用自己深厚的前端沉淀,将YUI3这个前端框架的能力借助Node延伸到服务器端,使得使用者摆脱了日常工作中一边写JavaScript一边写PHP所带来的上下文交换负担。 Node带来的高性能I/O用于实时应用。Voxer将Node应用在实时语音上。国内腾讯的朋友网将Node应用在长连接中,以提供实时功能,花瓣网、蘑菇街等公司通过socket.io实现实时通知的功能。 并行I/O... 查看全部[ 1.6 Node的使用者 ]
1.7 参考资源
本章参考的资源如下: http://www.infoq.com/cn/articles/what-is-nodejs https://github.com/popular/watched http://groups.google.com/group/nodejs/browse_thread/thread/85f6a3829bc64cb6 http://groups.google.com/groups/profile?enc_user=dPo6jggAAACthftLMWCfUq8U6obMz179 http://search.npmjs.org/ http://code.googl... 查看全部[ 1.7 参考资源 ]
2.1 CommonJS规范
首先,我想从模块为你娓娓道来Node。 JavaScript自诞生以来,曾经没有人拿它当做一门真正的编程语言,认为它不过是一种网页小脚本而已,在Web 1.0时代,这种脚本语言在网络中主要有两个作用广为流传,一个是表单校验,另一个是网页特效。另一方面,由于仓促地被创造出来,所以它自身的各种陷阱和缺点也被各种编程人员广为诟病。直到Web 2.0时代,前端工程师利用它大大提升了网页上的用户体验。在这个过程中,B/S应用展现出比C/S应用优越的地方。至此,JavaScript才被广泛重视起来。 在Web 2.0流行的过程中,各种前端库和框架被开发出来,它们最初用于兼容各个版本的浏览器,随后随着更... 查看全部[ 2.1 CommonJS规范 ]
2.2 Node的模块实现
Node在实现中并非完全按照规范实现,而是对模块规范进行了一定的取舍,同时也增加了少许自身需要的特性。尽管规范中exports、require和module听起来十分简单,但是Node在实现它们的过程中究竟经历了什么,这个过程需要知晓。 在Node中引入模块,需要经历如下3个步骤。 (1) 路径分析 (2) 文件定位 (3) 编译执行 在Node中,模块分为两类:一类是Node提供的模块,称为核心模块;另一类是用户编写的模块,称为文件模块。 核心模块部分在Node源代码的编译过程中,编译进了二进制执行文件。在Node进程启动时,部分核心模块就被直接加载进内存中,所以这部分核心模块引... 查看全部[ 2.2 Node的模块实现 ]
2.3 核心模块
前面提到,Node的核心模块在编译成可执行文件的过程中被编译进了二进制文件。核心模块其实分为C/C++编写的和JavaScript编写的两部分,其中C/C++文件存放在Node项目的src目录下,JavaScript文件存放在lib目录下。 2.3.1 JavaScript核心模块的编译过程 在编译所有C/C++文件之前,编译程序需要将所有的JavaScript模块文件编译为C/C++代码,此时是否直接将其编译为可执行代码了呢?其实不是。 1. 转存为C/C++代码 Node采用了V8附带的js2c.py工具,将所有内置的JavaScript代码(src/node.js和lib/*.j... 查看全部[ 2.3 核心模块 ]
2.4 C/C++扩展模块
对于前端工程师来说,C/C++扩展模块或许比较生疏和晦涩,但是如果你了解了它,在模块出现性能瓶颈时将会对你有极大的帮助。 JavaScript的一个典型弱点就是位运算。JavaScript的位运算参照Java的位运算实现,但是Java位运算是在int型数字的基础上进行的,而JavaScript中只有double型的数据类型,在进行位运算的过程中,需要将double型转换为int型,然后再进行。所以,在JavaScript层面上做位运算的效率不高。 在应用中,会频繁出现位运算的需求,包括转码、编码等过程,如果通过JavaScript来实现,CPU资源将会耗费很多,这时编写C/C++扩展模块来... 查看全部[ 2.4 C/C++扩展模块 ]
2.5 模块调用栈
结束文件模块、核心模块、内建模块、C/C++扩展模块等的阐述之后,有必要明确一下各种模块之间的调用关系,如图2-8所示。 C/C++内建模块属于最底层的模块,它属于核心模块,主要提供API给JavaScript核心模块和第三方JavaScript文件模块调用。如果你不是非常了解要调用的C/C++内建模块,请尽量避免通过process.binding()方法直接调用,这是不推荐的。 JavaScript核心模块主要扮演的职责有两类:一类是作为C/C++内建模块的封装层和桥接层,供文件模块调用;一类是纯粹的功能模块,它不需要跟底层打交道,但是又十分重要。 图2-8 模块之间的调用关系 ... 查看全部[ 2.5 模块调用栈 ]
2.6 包与NPM
Node组织了自身的核心模块,也使得第三方文件模块可以有序地编写和使用。但是在第三方模块中,模块与模块之间仍然是散列在各地的,相互之间不能直接引用。而在模块之外,包和NPM则是将模块联系起来的一种机制。 在介绍NPM之前,不得不提起CommonJS的包规范。JavaScript不似Java或者其他语言那样,具有模块和包结构。Node对模块规范的实现,一定程度上解决了变量依赖、依赖关系等代码组织性问题。包的出现,则是在模块的基础上进一步组织JavaScript代码。图2-9为包组织模块示意图。 图2-9 包组织模块示意图 CommonJS的包规范的定义其实也十分简单,它由包结构和包描述... 查看全部[ 2.6 包与NPM ]
2.7 前后端共用模块
谈论了许多后端模块的具体实现后,现在我们围绕CommonJS规范再次回到前端模块上。JavaScript在Node出现之后,比别的编程语言多了一项优势,那就是一些模块可以在前后端实现共用,这是因为很多API在各个宿主环境下都提供。但是在实际情况中,前后端的环境是略有差别的。 2.7.1 模块的侧重点 前后端JavaScript分别搁置在HTTP的两端,它们扮演的角色并不同。浏览器端的JavaScript需要经历从同一个服务器端分发到多个客户端执行,而服务器端JavaScript则是相同的代码需要多次执行。前者的瓶颈在于带宽,后者的瓶颈则在于CPU和内存等资源。前者需要通过网络加载代码,后者... 查看全部[ 2.7 前后端共用模块 ]
2.8 总结
CommonJS提出的规范均十分简单,但是现实意义却十分强大。Node通过模块规范,组织了自身的原生模块,弥补JavaScript弱结构性的问题,形成了稳定的结构,并向外提供服务。NPM通过对包规范的支持,有效地组织了第三方模块,这使得项目开发中的依赖问题得到很好的解决,并有效提供了分享和传播的平台,借助第三方开源力量,使得Node第三方模块的发展速度前所未有,这对于其他后端JavaScript语言实现而言是从未有过的。从一定的角度上讲,CommonJS规范帮助Node形成了它的骨骼。只有茁壮的根,才能培养出茂盛的枝叶,并成长为参天大树。正是这些底层的规范和实践,使得Node有序地发展着,摆脱... 查看全部[ 2.8 总结 ]
2.9 参考资源
本章参考的资源如下: http://www.commonjs.org http://npmjs.org/doc/README.html http://www.infoq.com/cn/articles/msh-using-npm-manage-node.js-dependence http://nodejs.org/docs/latest/api/modules.html http://addyosmani.com/writing-modular-js/ http://seajs.org/docs/ http://zh.wikipedia.org/zh/JavaScript h... 查看全部[ 2.9 参考资源 ]
书名: 深入浅出Node.js
作者: 朴灵
出版社: 人民邮电出版社
出版年: 2013-12-1
页数: 332
定价: CNY 69.00
装帧: 平装
丛书: 图灵原创
ISBN: 9787115335500