




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
內(nèi)容提要本書首先簡要介紹Node.js,然后通過各種示例講解Node.js的基本特性,再用案例式教學(xué)的方式講述Node.jsWeb開發(fā),Node.js進(jìn)階話題,最后展示如何將一個Node.js應(yīng)用部署到本向?qū)ode.js感,但沒有基礎(chǔ)的讀者,也可供已了解Node.js,并對Web前端/后端開發(fā)有Node.js開發(fā)指著BYVoid責(zé)任編輯王軍花執(zhí)行編輯人民郵電 市崇文區(qū)夕照寺街號電子郵件 http 印刷開本:800×1000印張字?jǐn)?shù):249千 2012年7月第1印數(shù):1—5000 2012年7月第1次印ISBN978-7-115-28399-定價:45.00 這本書講本書是一本Node.js的,寫給想了解Node.js的開發(fā)人員。我的目標(biāo)是使讀者通過閱讀本書學(xué)會使用Node.js進(jìn)行Web后端開發(fā)同時能熟悉驅(qū)動的異步式編程風(fēng)格,以便進(jìn)一步了解Node.js的許多高級特性,以及它所應(yīng)用的領(lǐng)域。1章“Node.js解它與JavaScript的深厚淵源。2章“安裝和配置Node.js及其基本運(yùn)行環(huán)境,同時你第3章“Node.js快速這一章講解Node.js的基礎(chǔ)知識,你將會學(xué)到如何Node.js的基本環(huán)境和工具進(jìn)行開發(fā)、此外這一章還詳細(xì)介紹了Node.js的模塊和包的系統(tǒng),這些都是開發(fā)中經(jīng)常會碰到的內(nèi)容。第4章“Node.js模塊這一章以全局對象、基本工具、、文件系統(tǒng)和HTTP為代表,介紹了 最常用的模塊。你將會在后面的章節(jié)及以后的開發(fā)中經(jīng)常與這些模塊打交道5Node.jsWeb實現(xiàn)路由控制、模板解析、會話管理、數(shù)據(jù)庫等功能,最終創(chuàng)建一個Web2.0。6章“Node.js署等內(nèi)容,最后還討論了Node.js 附錄A“JavaScript這些特性在瀏覽器端的JavaScript開發(fā)中并沒有受到應(yīng)有的重視,而在Node.js中卻十分常見,閱讀這個附錄可以幫助你更好地理解并運(yùn)用JavaScript進(jìn)行復(fù)雜的開發(fā)。附錄B“Node.jsNode.js代碼風(fēng)格的一些約定,遵守這些約定可以讓你的代碼更清晰、本書的目標(biāo)讀者是想要學(xué)習(xí)Node.js,但沒有任何系統(tǒng)的經(jīng)驗的開發(fā)者。如果你聽同時還可以掌握一些使用JavaScript進(jìn)行函數(shù)式編程的方法。的語言,如Java或C。熟悉瀏覽器端JavaScript的讀者將很容易學(xué)會Node.js的許多特性,包括式編程、閉包、回調(diào)函數(shù)等,因為這些特性已經(jīng)在瀏覽器中被廣泛應(yīng)用。同時,你還可以學(xué)到Node.js 利的。你還會對JavaScript有一個全新的認(rèn)識,因為服務(wù)端的JavaScript中沒有DOM和JavaScript但是了解C、Java、C++、C#JavaScript的語言特Node.jsJavaScript語言的特別之處,Web后端開發(fā)(PHP、ASPnet、RubyonRails、Django等)的讀者,Node.jsNode.js和這些傳統(tǒng)的框架有很大的區(qū)別,因為它使用了式編程和異步I/O,所以你需要改變一些已有的思維方式。同時,你還能享受到Web前后端緊密配合帶來的新鮮感,并可能對Ajax有全新的認(rèn)識。 .cn/js/看看JavaScript的。你只要了解基礎(chǔ)知識就地學(xué)會Node.js經(jīng)常使用到的那些特性。如果你想更加深入系統(tǒng)地學(xué)習(xí)JavaScript,推薦閱讀MozillaJavaScript指南。本書從第3章開始,將介紹如Node.js開發(fā),你應(yīng)該仔細(xì)閱讀這一章。第4章是一些最基本的模塊介紹,涉及Node.js模塊的基本風(fēng)格,這可能會幫助你理解后面介紹的API5章是一個實彈的實戰(zhàn)演練,跟隨這一章的每個步驟你就可以用Node.js實現(xiàn)一個真正的Web應(yīng)用,體驗開發(fā)的成就感。第6章則是一些進(jìn)階話題,你會在這里接觸到Node.js的一些深層次概念,同時你還將學(xué)會如何真正部署Node.js應(yīng)用。通讀本書,你將會學(xué)到Node.js的很多東西,但如果想完全掌握它,我建議你親自嘗試運(yùn)行本每一段代碼。本書的所有代碼可以在htt /project/node上找到。①除此之外,你最好自己用Node.js做一個項目,因為通過實踐你會遇到很多問題,解決這些問題可以大大加深對Node.js的理解。注意,了互聯(lián)網(wǎng)網(wǎng)上的資源,比如Node.js的API文檔。我強(qiáng)烈推薦你去CNodeJS社區(qū)看看/,這里匯集了許許多多中國優(yōu)秀的————————— 讀者也可以到圖靈社區(qū) .cn)本書的頁面上源代碼或提交勘誤?!幷?Node.js開發(fā)者。他們每天都在討論著大量有關(guān)Node.js各個方面的話題,你可以在上面獲得很多幫助。同時,CNodeJS社區(qū)的也是用Node.js寫成的,而且是開源的,它是一個非常好的讓你了解如何用Node.js開發(fā)的實例。 { o,}在正文之中,偶爾還會穿插一些提示和警告,例致感謝CNodeJS社區(qū)的賈超、田永強(qiáng)和微軟亞洲的楊懋,以及VMware公司的柴可感謝弓辰開發(fā)的Rime輸入法③,我用它完成了本書的創(chuàng)—————————①李垚是果殼網(wǎng)的作者之一,他的個人是 /②蕭騏是DiveintoPython的譯者,活躍在linuxtoyMac上使用,其是http 第1章Node.js簡 Node.js能做什 異步式I/O與驅(qū) Node.js架構(gòu)簡 Node.js與PHP+ Java與 敖軟的加入—— 瀏覽器兼容性問 引擎效率和JavaScript未 服務(wù)端JavaScript的重 CommonJS規(guī)范與實 參考資 第2章安裝和配置 安裝前的準(zhǔn) 快速安 Windows系統(tǒng)上 Linux版上安裝 MacOSX上安裝 編譯源代 在POSIX系統(tǒng)中編 在Windows系統(tǒng)中編
安裝Node包管理 安裝多版本管理 參考資 第3章Node.js快速開始用Node.js編 o Node.js命令行工 建立HTTP服務(wù) 異步式I/O與式編 阻寒與線 回調(diào)函 模塊和 什么是模 創(chuàng)建及加載模 創(chuàng)建 Node.js包管理 調(diào) 命令行調(diào) 調(diào) 使用Eclipse調(diào)試 node-inspector 參考資 第4章Node.js模 全局對 全局對象與全局變 4.5.2HTTP客戶 4.6參考資 第5章使用Node.js進(jìn)行Web開 準(zhǔn)備工 使用http模 快速開 安裝 建立工
2目錄常用2目錄常用工具 路由規(guī) 4.2.1 界面設(shè) 4.2.2 使用 驅(qū)動 用和登 4.3.1數(shù)據(jù) 4.3.2error會話支 4.3.3組又 和登 文件系統(tǒng) 頁面權(quán)限控 服務(wù)器與客戶 5.7.2用戶頁 首 下一 5.8參考資 第6章Node.js進(jìn)階話 模塊加載機(jī) 模塊的類 按路徑加栽模 通過查找加栽模 加栽緩
啟動服務(wù) 工程的結(jié) 路由控 工作原
6.1.5加栽順 控制 循環(huán)的陷 解決控制流難 創(chuàng)建路由規(guī) 路徑匹 REST風(fēng)格的路由規(guī) 控制權(quán)轉(zhuǎn) 模板引 什么是模板引 使用模板引 頁面布
Node.js應(yīng)用部 日志功 使用cluster模 啟動共享80端 Node.js不是銀 參考資 片段視 視圖助片段視 視圖助 附錄BNode.js編程規(guī) 建 功能分 索 Node.js簡 1 1章Node.jsNode.js,或者Node,是一個可以讓JavaScript運(yùn)行在服務(wù)器端的平臺。它可以讓程序一樣Node.js輕松地進(jìn)行服務(wù)器端應(yīng)用開發(fā),Python、Perl、PHP、Ruby能做的事情Node.js幾乎都能做,而且可以做得更好。Node.js最初是由RyanDahl發(fā)起的開源項目,后來被Joyent公司注意到。Joyent公司將RyanDahl招入旗下因此現(xiàn)在的Node.js由Joyent公司管理并盡管它誕生的時(2009 manager,npm,有MySQL、PostgreSQL、MongoDB數(shù)據(jù)庫接口,有模板語言解析、CSS生成工具、郵件、加密、圖形、調(diào)試支持,甚至還有圖形用戶界面和操作系統(tǒng)API工具。由VMware公司建立的云計算平臺CloudFoundry率先支持了Node.js。2011年6月,微軟宣布與Joyent公司合作,將Node.js移植到Windows,同時WindowsAzure云計算平臺也支持Node.js。Node.js目前現(xiàn)在開始,一同探索Node.js的美妙世界吧!Node.js是什Node.js不是一種獨(dú)立的語言,與PHP、Python、Perl、Ruby的“既是語言也是平臺”不同。Node.jsJavaScriptCakePHP、Django、Rails。Node.js更不jQuery、ExtJS相提并論。Node.jsJavaScript運(yùn)行在服務(wù)端的開發(fā)平臺,它讓JavaScript成為語言世界的一等公民,在服務(wù)端堪與PHP、Python、Perl、Ruby平起平坐。Node.jsWeb前端和后端技術(shù)的基礎(chǔ)上總結(jié)并提煉出Web開發(fā)經(jīng)驗的集大成者。Node.js可以作為服務(wù)器向用戶提PHP、Python、RubyonRails相比,它跳Apache、NginxHTTP服務(wù)器,直接面向前端開發(fā)。Node.js的許多設(shè)計理念與經(jīng)典架構(gòu)(LAMP)有著很大的Node.js說起JavaScript,不得不讓人想到瀏覽器。傳統(tǒng)意義上,JavaScript是由ECMAScriptNode.js能做什 文檔對象模型(DOM)和瀏覽器對象模型(BOM)組成的,而Mozilla則JavaScript由CoreJavaScript和JavaScript組成。之所以會有這種,是因為JavaScript和瀏覽器可以認(rèn)為,Node.jsJavaScriptCoreJavaScriptECMAScript的一個實現(xiàn),不包含DOM、BOM或者JavaScript。這是因為Node.js不運(yùn)行在瀏覽器中,所Node.jsJavaScript運(yùn)行在瀏覽器之外的平臺。它實現(xiàn)了諸如文件系統(tǒng)、模塊、APICoreJavaScript沒有或者不完善的功能。歷史上將JavaScript移植到瀏覽器外的計劃不止一個,但Node.js是最出色的一個。隨著Node.js的成功,各種瀏JavaScriptCommonJS規(guī)范。CommonJS試圖擬定一套完整的JavaScript規(guī)范,以彌補(bǔ)普通應(yīng)用程序所需的API,譬如文件系統(tǒng)、命令行、模塊管理、函數(shù)庫集成等功能。CommonJS制定者希望眾多服務(wù)端JavaScript實現(xiàn)遵循CommonJS規(guī)范,以便相互兼容和代碼復(fù)用。Node.js的部份實現(xiàn)遵循了CommonJS規(guī)范,但Node.js的JavaScript引擎是V8,來自Chrome項目。V8號稱是目前世界上最快的JavaScript引擎,經(jīng)歷了數(shù)次引擎,它的JIT(Just-in-timeCompilation,即時編譯)執(zhí)行速度已經(jīng)快到了接近本地代碼的執(zhí)行速度。Node.js不運(yùn)行在瀏覽器中,所以也就不存在JavaScript的瀏覽器兼容性問題,你可以放心地使用JavaScript語言的所有特性。Node.js能做什JavaScript為客戶端而生,Node.js為網(wǎng)絡(luò)而生。Node.js能做的遠(yuǎn)不止開發(fā)一個網(wǎng)Node.js,你可以輕松地開發(fā):0具有復(fù)雜邏輯的0Web0WebSocket服務(wù)器0TCP/UDP0命令行工具0交互式終端程序00單元測試工具0客戶端JavaScript編譯器Node.js內(nèi)建了HTTP服務(wù)器支持,也就是說你可以輕而易舉地實現(xiàn)一個和服務(wù)器PHP、PerlPHP的時候,JApache之類的 1章Node.jsHTTP服務(wù)器,然后通過HTTP服務(wù)器的模塊加載或CGI調(diào)用,,能將PHP的執(zhí)行結(jié)果呈現(xiàn)給用戶。而當(dāng)你使用Node.js時,不用額外搭建一個HTTP服務(wù)器,因為Node.js本身Node.js還可以部署到非網(wǎng)絡(luò)應(yīng)用的環(huán)境下,比如一個命令行工具。Node.js還可以調(diào)用C/C++來實現(xiàn)。異步式I/O與驅(qū)Node.js最大的特點就是采用異步式I/O與驅(qū)動的架構(gòu)設(shè)計。對于高并發(fā)的解決方式的請求方式,避免了頻繁的上下文切換。Node.js在執(zhí)行的過程中會一個隊列,程序在執(zhí)行時進(jìn)入循環(huán)等待下一個到來,每個異步式I/O請求完成后會被推送到例如,對于簡單而常見的數(shù)據(jù)庫查詢操作,按照傳統(tǒng)方式實現(xiàn)的代res=db.query('SELECT*fromsome_table');CPU時間來處理內(nèi)存上下文切換,看看Node.js是如何解決這個問題的db.query('SELECT*fromsome_table',{這段代碼中db.query的第二個參數(shù)是一個函數(shù),我們稱為回調(diào)函數(shù)。進(jìn)程在執(zhí)行到當(dāng)數(shù)據(jù)庫查詢結(jié)果返回時,會將發(fā)送到隊列,等到線程進(jìn)入循環(huán)以后,,會調(diào)Node.js的異步機(jī)制是基于的,所有的磁盤I/O、網(wǎng)絡(luò)通信、數(shù)據(jù)庫查詢都以非阻 的方式請求,回的結(jié)果由循環(huán)來處理。圖1-1?述了這個機(jī)制。Node.js進(jìn)程在同一時刻只會處理一個,完成后立即進(jìn)入循環(huán)檢查并處理后面的。這樣做的好處是,CPUI/O操作并行執(zhí)行。對于低速連接,Node.js只是在隊列中增加請求,等待操作系統(tǒng)的回應(yīng),因而不會有任何多線程開銷,很大程度上可以提高Web應(yīng)用的健壯性,防止。圖1-1循Node.js的性Node.js用異步式I/O和驅(qū)動代替多線程,帶來了可觀的性能提升。Node.js除了使圖1-2是Node.js架構(gòu)的示意圖。libuv通過封裝libevlibeio來利用epollkqueue而在Windows下,libuv使用了—————————POSIX(PortableOperatingSystemInterface)是一套操作系統(tǒng)API規(guī)范。一般而言,遵POSIX規(guī)范的操作系統(tǒng)指的是UNIX、Linux、MacOSX等。IOCP(Input/OutputCompletionPort,輸入輸出完成端口)機(jī)制,以在不同平臺下實現(xiàn)同圖1-2Node.jsNode.jsPHPSnoopyxdNode.jsPHP+Nginx組合,結(jié)果顯示在3000并發(fā)連接、30秒的測試下,輸出“oworld"請求:0PHP每秒響應(yīng)請求數(shù)為3624,平均每個請求響應(yīng)時間為0.390Node.js每秒響應(yīng)請求數(shù)為7677,平均每個請求響應(yīng)時間為0.13秒。0PHP每秒響應(yīng)請求數(shù)為1293,平均每個請求響應(yīng)時間為0.820Node.js每秒響應(yīng)請求數(shù)為2999,平均每個請求響應(yīng)時間為0.33秒。關(guān)于Node.js的性能優(yōu)化及生產(chǎn)部署,我們會在第6章詳細(xì)討論。JavaScript簡作為Node.js的基礎(chǔ),JavaScript是一個完全為網(wǎng)絡(luò)而誕生的語在今天看來,JavaScript是這樣。多年以來,JavaScript因為其低效和兼容性差而廣受垢病,一直是一個嘲笑的“丑小鴨它在成熟之前經(jīng)歷了無數(shù)和坎坰,個中究竟,還要從它的誕生講起。JavaScript首次出現(xiàn)在1995Node.jsJavaScript的誕生決不是(的工具配合,使能夠在瀏覽器中運(yùn)行,因此ScriptEase成為了第一個客戶端語言。網(wǎng)景公司也想獨(dú)立開發(fā)一種與ScriptEase相似的客戶端語言,BrendanEich①接受了如者,個的工數(shù)LivireLiveireveScrptbJava在JavaScript誕生之前,Javaapplet②曾經(jīng)被熱炒Sun公司一直在不遺余力地推廣Java,宣稱Javaapplet將會改變?nèi)藗優(yōu)g覽網(wǎng)頁的方式。然而市場并沒有像Sun公司預(yù)期的那樣好,這很大程度上是因為Javaapplet速度慢而且操作不便。網(wǎng)景公司的市場部門抓住了這個機(jī)遇Sun合作完成了LiveScript實現(xiàn),并在網(wǎng)景的Navigator2.0發(fā)布前LiveScript更名為具,目的之一就是為了幫助開發(fā)者更好地Javaapplet。JavaJavaScript這兩個不相千的語言。兩者除了名字相似和歷史淵源之外,幾乎沒有任何關(guān)系?,F(xiàn)在看來,從到郵件列表,從到閉,能把Java和JavaScript區(qū)分開的倒是少數(shù)③。圖1-3是知道上的“Java相關(guān)"分類。圖1- 知道上的“Java相關(guān)"分—————————①BrendanEich稱為JavaScript之父,他完全沒想到自己當(dāng)年無心設(shè)計的一個語言會成為今天最流行的網(wǎng)絡(luò)腳,③BrendanEich為此抱憾不已,他后來在一個名為“JavaScriptatTenYears"(JavaScript這10年)的稿“Don’tletmarketingnameyourlanguage.(不要為了決定語言名稱。微軟的加入——就在網(wǎng)景公司如H中天之時,微軟的InternetExplorer3隨Windows95OSR2銷售致使微軟后來聲名狼藉(以及一系列的反但I(xiàn)nternetExplorer3的成功卻有目共?,其成功不僅僅在于市場?銷策略,也源于產(chǎn)本身。InternetExplorer3是一個??,因為它也實現(xiàn)了??于JavaScript的?端語言——JScript,除此之外還有微軟的t?本行“VBScript。JScript的誕生成為JavaScript發(fā)展的一個重要里程碑,標(biāo)志了頁時代的全面到來。圖1-4Windows95InternetExplorer3。圖1-4Windows95InternetExplorer標(biāo)準(zhǔn)化最初JavaScript并沒有一個標(biāo)準(zhǔn),因此在不同瀏覽器間有各種各樣的兼容性的問題。InternetExplorer占領(lǐng)市場以后這個問題變得更加,因此JavaScript的標(biāo)準(zhǔn)化勢在必行。在1996年,JavaScript標(biāo)準(zhǔn)由諸多軟件廠商共同提交給ECMA(歐洲計算機(jī)制造商。ECMA通過了標(biāo)準(zhǔn)ECMA-262,也就是ECMAScript。緊接著國際標(biāo)準(zhǔn)化組織也采納了ECMAScript標(biāo)準(zhǔn)(ISO-16262。在接下來的幾年里,瀏覽器開發(fā)者們就開始以ECMAScript作為規(guī)范來JavaScript解析引擎ECMAScript誕生至今已經(jīng)有了多個版本,的版本是在2009年12月發(fā)布的ECMAScript5,而到2012年為止,業(yè)界普遍支持的ECMAScript3,只有新版的Chrome和Firefox實現(xiàn)了ECMAScript5。ECMAScripttp@、WMLScript@也是ECMAScript的實現(xiàn)。ECScriptJavaScrptvtaacit代碼會在不同的瀏覽器中呈現(xiàn)出不同的效果,甚至在一個瀏覽器中可要注意的是,瀏覽器的兼容性問題并不只是由JavaScript的兼容性造成的,而是DOM、BOM、CSS解析等不同的行為 ?的。?維網(wǎng)聯(lián)?(WorldWideWebConsortium,W3C)針引擎效率和JavaScript的未JavaScriptBrendanEichNavigator中開發(fā)的,它的名字叫做SpiderMonkey。SpiderMonkey在這之后還用作MozillaFirefox1.0~3.0版本的引擎,而從Firefox3.5開始換為TraceMonkey,4.0版本以后又換為JaegerMonkey。Chrome的JavaScriptV8V8Node.jsInternetExplorer9開始使用其新的JavaScript引擎Chakra。@過去,JavaScript一直不重視,很大程度上是因為它效率不高——不僅速度慢,還Node.js也不會這么快誕生。—————————①ActionScript最初是Adobe公司Flash的一部分,用于控制動畫效果,現(xiàn)在已經(jīng)被廣泛應(yīng)用在Adobe的各項②QtScript是Qt4.3.0以后引入的工具WMLScriptWAP協(xié)議的一部分,用于WML(WirelessMarkupLanguage)頁面@除此以外還KJS(Konqueror)、Nitro(Safari)、Carakan(用于Opera)JavaScript2008MozillaFirefox的一次改Firefox3.0JavaScript性能大幅提升,從而了JavaScript引擎之間的效率競賽。緊接著WebKit①開發(fā)團(tuán)隊了Safari4新的JavaScript引擎SquirrelFish(后來改名Nitro)可以大幅度提升執(zhí)行速度。Chrome剛剛誕生就因它的JavaScript性能而備受稱贊,但隨著WebKitSquirrelfishExtremeMozilla的TraceMonkey技術(shù)的出現(xiàn),Chrome的JavaScript引擎速度被了,于是Chrome2發(fā)布時使用了更快速的V8引擎。V8一出場就以其一騎絕塵般的速度打敗了所有對手,一度成為JavaScript引擎的速度之王。于是其他瀏覽器的開發(fā)者開始奮力追趕,與以往不同的是,InternetExplorer也加入了這次競賽,并取得了不俗的成績。JavaScript引擎的效率已經(jīng)不相上下,通過不同引擎根據(jù)不同測試基準(zhǔn)測得的結(jié)果各有千秋。更有趣的是,JavaScript的效率在不知不覺中已經(jīng)了其他所有傳統(tǒng)的語言,并帶動了解釋器的革新運(yùn)動。JavaScript已經(jīng)成為了速度最快的語盡管如此,我們不能否認(rèn)JavaScript還有很多不完美之處,譬如一些的特性,這幾乎成了JavaScript批評和的焦點。如今JavaScript還在繼續(xù)發(fā)展,ECMAScript6CoffeeScriptJavaScript語言特性的不足而誕生的語言。也專門針對客戶端JavaScript不完美的地方推出了Dart語言。隨著大規(guī)模的應(yīng)用推廣,我們有理由相信JavaScript會變得越來越好。JavaScriptNode.js并不是第一個嘗試使JavaScript運(yùn)行在瀏覽器之外的項目。追根溯源,在JavaScript誕生之初,網(wǎng)景公司就實現(xiàn)了服務(wù)端的JavaScript,但由于需要支付一大筆費(fèi)用人見識到JavaScript在服務(wù)器開發(fā)的,是微軟的ASP。時并不是很受歡迎,一方面是早期的JScriptJavaScript兼容較差,另一方面微軟大力推廣的系列概念的提出,JavaScript成了前端開發(fā)的代名詞,同時服務(wù)端JavaScript也逐漸皿忘?!賅ebKit是蘋果公司在設(shè)計Safari時開發(fā)的瀏覽器引擎,于KHTML和KJS項目的分支。WebKit包含了一個網(wǎng)頁引擎WebCore和一個引擎JavaScriptCore,但由于JavaScript引擎越來越獨(dú)立,WebKit逐漸成為了WebCore的代名詞。 直至幾年前,JavaScript的種種優(yōu)勢才被重新提起,JavaScript又具備了在服務(wù)端流行的條件,Node.js應(yīng)運(yùn)而生。與此同時,RingoJS也基Rhino實現(xiàn)了類似的服JavaScript平CouchDB、MongoDBJavaScriptJSON作為其數(shù)據(jù)語言,基于JavaScript的服務(wù)端實現(xiàn)開始遍地開花。CommonJS正如當(dāng)年為了統(tǒng)一JavaScript語言標(biāo)準(zhǔn),人們制定了ECMAScript規(guī)范一樣,如今為了統(tǒng)一JavaScript在瀏覽器之外的實現(xiàn),CommonJS誕生了。CommonJS試圖定義一套普通應(yīng)用程序使用的API,從而JavaScript標(biāo)準(zhǔn)庫過于簡單的不足。CommonJS的終極目標(biāo)是制C++標(biāo)準(zhǔn)庫一樣的規(guī)范,使得基CommonJSAPI的應(yīng)用程序可以在不同的環(huán)境++中立,CommonJS不參與標(biāo)準(zhǔn)庫實現(xiàn),其實現(xiàn)交給像Node.js之類的項目來完成。圖1-5是CommonJS的各種實現(xiàn)。圖1-5CommonJS(odules(pakge(system(binary(console(encodings(filesystems(sockets試(unittesting)等部分。目前大部分標(biāo)準(zhǔn)都在擬定和討論之中,已經(jīng)發(fā)布的標(biāo)準(zhǔn)有Node.js是目前CommonJS規(guī)范最熱門的一個實現(xiàn),它基于CommonJSModules/1.0規(guī)范實現(xiàn)了Node.js的模塊,同時隨著CommonJS規(guī)范的更新,Node.js也在不斷跟進(jìn)。由于目CommonJS大部分規(guī)范還在起草階段,Node.js已經(jīng)率先實現(xiàn)了一些功能,并將其反饋給CommonJSNode.js并不完全遵iCommonJS規(guī)范。這是所有規(guī)范制定者參考資Node.js:“再談select、iocp、epoll、kqueue及各種I/O復(fù)用機(jī)制”: “巔峰對決:node.js和php性能測試”:/blog/static/ “UpdateonmyNode.jsMemoryandGCBenark”:htt /2010/09/29/“JavaScriptatTenYears”:QtScript:WebKitOpenSourceProject:CommonJSAPISpecifications /specs/RingoJS:MongoDB:/CouchDB:Persevere:《JavaScript高級程序設(shè)計(第3版》NicholasC.Zakas著,人民郵電《JavaScript指南(第5版》FlanaganDavid著,機(jī)械工業(yè)安裝和配置 2在使用Node.js開發(fā)之前,我們首先要配置好開發(fā)環(huán)境。本章的主要內(nèi)容0Linux、Windows、MacOSXNode.js0POSIXWindowsNode.js0npm(Node.js包管理器0Node.js安裝前的準(zhǔn)Node.jsPOSIXGNU/Linux、MacOSX、Solaris等。Node.js起初不支持Windows,只能運(yùn)行在cygwin上,而0.6版本以后就支持Windows了,本節(jié)后面會詳述。從2009年誕生至今,Node.js一直處在快速發(fā)展的時期,因此很多方法、技巧都會迅速被新的技術(shù)取代,本書內(nèi)容也不例外。就在不久前,大家還都推薦通過編譯源代碼安裝Node.js,而現(xiàn)在已經(jīng)有了成安裝包系統(tǒng)。我們推薦你盡量通過Node.js或操作系統(tǒng)版提供的途徑進(jìn)行安裝,除非你想獲得的版本,否則就不要費(fèi)力編譯了。Node.js從0.6Windows上了(cygwin或者其他虛擬環(huán)境WindowsAzure宣布了Node.js完全支持。這對微軟來說簡直是破天荒的舉動,因為一貫具有“開源死敵”之稱Node.js,不得不令人膛目結(jié)舌。盡管如此,Node.jsWindowsPOSIXnpm提供的第模塊中體現(xiàn)得尤為突出這主要是因為許多第的模塊需要編譯原生的C/C++代碼,其中編譯框架和系統(tǒng)調(diào)用很多都Linux為范本的,與Windows不兼容。筆者不建議在Windows上進(jìn)Node.js開發(fā)或部署,當(dāng)然出于學(xué)習(xí)目的,這些影響也是無關(guān)緊要的。相信,Node.js接下來的小節(jié)詳細(xì)介紹Node.js的安裝方法快速安Windows系統(tǒng)上安裝在Windows上安裝Node.js十分方便,你只需要 接,然后選擇WindowsInstaller,安裝包。完成后打開安裝包(如圖2-1所示點擊快速安 Next即可自動完成安裝圖2-1Windows安裝程序不會詢問你安裝路徑,Node.js會被自動安裝到C:\ProgramFiles\nodejs或C:\ProgramFiles(x86)\nodejs(64位系統(tǒng)),并且會在系統(tǒng)的PATH環(huán)境變量中增加該目錄,因此我們可以在Windows令提示符中直接運(yùn)行node。為了測試是否已經(jīng)安裝成們在運(yùn)行中輸入cmd,打開命令然后node,將會進(jìn)入Node.js的交互模式,如圖2-2所示。圖2-2WindowsNode.jsnpm圖2-2,我們可以在命令提示符中直接輸入npm來使用它。Linux版上安裝Node.js目前還處在快速變化的時期,它的速度要遠(yuǎn)遠(yuǎn)大于Linux版的周期,因此各個Linux版的軟件包管理器中提供的Node.js往往都比較過時。盡管如表2-1在Linux版中獲取 apt-getinstallFedora/RHEL/CentOS/Scientific yuminstall zypperinstallArch pacman-S如果你需要用軟件包管理器來獲得較新版本的Node.js,就要根據(jù)不同的版選擇第 MacOSX上安裝Node.js專門提供了MacOSX的安裝包,你可以在找到,然后選擇MacintoshInstaller,安裝包。完成后運(yùn)行安裝包(如圖2-3所示圖2-3MacOSXNode.js和npm會被安裝到 下,安裝過程中需要系統(tǒng)管理員權(quán)限。編譯源代 nodeNode.js-bash:nodecommandnotfound,說明沒有正確安裝,需要重新運(yùn)行安裝包或者采取其他形式Node.js。編譯Node.js0.6版本開始已經(jīng)實現(xiàn)了源代碼級別的跨平臺,因此我們可以使用不同的編譯命 后選擇SourceCode,正式發(fā)布的源碼包。如果你需要開發(fā)中的版本,可以通過/joyent/node/zipball/master獲得,或者在命令行下輸入gitclonePOSIXPOSIX系統(tǒng)中編譯Node.js需要三個工具OC++gccOPython2.5PythonOlibssl-devSSL/TLS如果你使用Linux,那么你需要使用g來編譯Node.js。在Debian/Ubuntu中,你可以通過apt-getinstallg++命令安裝g++。在Fedora/Redhat/CentOS中,你可以使用yuminstallgcc-c++安裝。如果使用的是MacOSX,那么需要安裝Xcode。默認(rèn)情況下,系統(tǒng)安裝盤中會有Xcode,可以從光盤中安裝,或者h(yuǎn)ttps://d /xcode/的版本。MacOSX和幾乎所有的Linux版都內(nèi)置了Python,你可以在終端機(jī)輸入命令python--version檢查Python的版本,可能會顯示Python2.7.2或其他版本。如果你發(fā)現(xiàn)版本號小于2.5或者直接出現(xiàn)了commandnotfound,那么你需要通過軟件包管理器獲得一個新版本的Python,或者到一個。libssl-dev是調(diào)用OpenSSL編譯所需的頭文用于提供SSL/TLS加密MacOSXXcodelibssl-devDebian/Ubuntuapt-getinstalllibssl-dev命令安裝。在Fedora/Redhat/CentOS中,你可以通過yuminstallopenssl-devel命令安裝。同樣,你也可以一個。接下來,進(jìn)入Node.js源代碼所 ,運(yùn)行sudomake之后大約等待20分鐘,Node.js就安裝完成了,而且附帶安裝了npm如果你使用MacOSX,還可以嘗試使用homebrew編譯安裝Node.js。首先在/homebrew/獲取homebrew,然后通過以下命令即可自動解析編譯依賴并安裝brewinstall在WindowsNode.js在Windows下只能通過VisualStudio編譯因此你需要首先安裝VisualStudio或者免費(fèi)的VisualStudioExpress。你還需要安裝Python2(2.5以上的版本,但要),可以在取得。安裝完P(guān)ython以后請確保在PATH環(huán)境變量中添python.exe所在 ,如果沒有則需要手動在”系統(tǒng)屬性”中添加一切準(zhǔn)備好以后,打開命令提示符,進(jìn)入Node.js源代碼所在 進(jìn)行編譯C:\Users\byvoid\node- '-Dtarget_Projectfilesgenerated.C:\ProgramFiles warningMSB8012:http_parser.vcxproj->C:\Users\byvoid\node-v0.6.12\js2c,andalsojs2c_experimental大約等待20分鐘,編譯完成。在Release子下面會有一個node.exe文件,這就是我們編譯的唯—目標(biāo)也許有些令人驚訝Node.js編譯后只有一個node.exe文件說明Node.js的核心非常小巧精悍。直接運(yùn)行node.exeNode.js的交互模式,在系統(tǒng)PATH環(huán)境變量中添加node.exe文件所在的,這樣就可以在命令行中運(yùn)行node命令了,剩下的工作就是手動安裝npm了。Node包管Node包管理器(npm)是一個由Node.js提供的第包管理工具,就像PHP的Pear、PythonPyPI一樣。npm是一個完全由JavaScript實現(xiàn)令行工具,通過Node.js?行,因此嚴(yán)格來講它不屬于Node.js的一部分。在最初的版本中,我們需要在安裝完Node.js以后手動安裝npm。但從Node.js0.6開始,npm已包含在包中了,我們在Windows、Mac上安裝包和源代碼包時會自動同時安裝npm。如果你是在Windows下手動編譯的,或是在POSIX系統(tǒng)中編譯時指定了--without-參數(shù),那就需要手動安裝npm了。提供了npm幾種不同的安裝方法,通安裝多版本管理 你只需要執(zhí)行以下命curl|如果安裝過程中出現(xiàn)了權(quán)那么需要在root權(quán)限下執(zhí)行上面的語或者使用sudocurl|sudo其他安裝方法,譬如從git中獲取npm的分支,可以參考README.html上的說明安裝多版本管迄今為止Node.js更新速度還很快,有時候新版本還會將舊版本的一些API,以至一個相對穩(wěn)定的環(huán)境。基于這種需求,Node.js的社區(qū)開發(fā)了多版本管理器,用于在一臺機(jī)器上多個版本的Node.js實例,方便按需切換。Node多版本管理器(NodeVersionManager,nvm)是一個通用的叫法,它目前有許多不同的實現(xiàn)。通常我們說的nvm/creationix/nvm或者 薦使用visionmedia/n,此小節(jié)就以它為例子介紹Node多版本管理器的用法。nNoden,如果你已經(jīng)安裝好了Node.js和npm環(huán)境,就可以直接使用npminstall-gn命令來安裝n當(dāng)然你可能會問如果完全通過n來管理Node.js,那么沒安裝之前哪來的npm呢?事實上,n并不需要Node.js驅(qū)動,它只是bash,使用npm安裝只是采取一種簡便 /visionmedia/n它的代碼,然后使用makeinstall命令安裝。nn不支Windowsnnhelp$n--Usage:n[options][COMMAND]—————————①事實上,n它曾經(jīng)叫做nvm,后來改名為n Outputversionsnlatest[config...] Installoractivatethelatestnodereleasen<version>[config...] Installand/orusenode<version>nuse<version>[args...]Executenode<version>with[args...]nbin<version> Outputbinpathfor<version>nrm<version Removethegivenn-- Outputthelatestnodeversionnls Outputtheversionsofnodeavailable-V,-- Outputcurrentversionof-h,--help Disyhelpinformation 運(yùn)行n版本號可以安裝任意已發(fā)布版本的Node.js,n會從 $n {'target_defaults':{'cflags':'defines':'include_dirs':[],'libraries':['-lz']},'variables':{'host_arch':'node_install_npm':'true','node_install_waf':'node_prefix':'/usr/local/n/versions/0.7.5','node_shared_cares':'false','node_shared_v8':'false','node_use_dtrace':'false','node_use_openssl':'true','node_use_system_openssl':'false','target_arch':'x64','v8_use_snapshot':'true'}}creating./config.gypicreatingmake-Cout參考資 CC(target)/usr/local/n/node-v0.7.5/out/Release/obj.target/http_parser/deps/LIBTOOL- /usr/local/n/node-Node.js版本,即可以直接使用node命令行調(diào)用的版本:$n*和安裝新版本一樣,運(yùn)行n版本號也可以在已安裝的Node.js實例中切換環(huán)境,再運(yùn)$n*$node-vnusescript.js直接指定Node.js的運(yùn)$nuse0.6.11包 版軟件源、手動編譯)你必須通過n安裝Node.js才能管理多本的Node.js關(guān)于n的細(xì)節(jié),請它的項目主 /visionmedia/n獲取信息參考“BuildingandInstalling /joyent/node/wiki/Installation“Nodepackagemanager”:html“Nodeversion /visionmedia/n0“深入淺出Node.js(一):Node.js&NPM的安裝與配置”:ht 0“Node.jsNowRunsNativelyonWindows”:ht 0“如何在MacOSXLion上設(shè)定node.js的開發(fā)環(huán)境”:http how-to-setup-a-node-js-development-environment-on-mac-osx-lion/。Node.js快 3Node.js是一個方興未艾的技術(shù)。一直以來,關(guān)于Node.js的宣傳往往針對它”與眾不同D編寫第一個Node.js程序;D異步式I/O和循環(huán);D模塊和包;D調(diào)試讓我們開始這個激動人心的旅程開始Node.js用Node.js編程是一件令人愉快的事情,因為你將開始用的思維和風(fēng)格編寫代碼。你會發(fā)現(xiàn)像這樣的語言是很容易的,可以快速了解到它的細(xì)節(jié),然后掌握它。o好了,讓我們開始實現(xiàn)第一個Node.js程序吧。打開你常用的文本編輯器,在其中輸 o將文件保存為oworld.js,打開終端,進(jìn)入oworld.js所在 ,執(zhí)行以下命令 如果一切正常,你將會在終端中看到輸出oWorld。很簡單吧?下面讓我們來解釋一下這個程序的細(xì)節(jié)。consoleNode.js提供的控制臺對象,其中包含了向標(biāo)準(zhǔn)輸出寫入的操作,如console.log、console.error等。console.log是我們最常用的輸出指Cprintf%d、%s變量console.log('%s:%d', o',輸出的是o:25。這只是一個簡單的例子,如果你想了解console對象的詳細(xì)功能,請參見4.1.3節(jié)。Node.js面的oWorld示例中,我們用到了命令行中的node命令,輸入node--可以看到詳細(xì)的幫助信Usage:node[options][-escript|script.js][arguments]nodedebugscript.js[arguments]-v,-- printnode's-e,--eval evaluate-p,-- printresultofv8- printv8commandline-- printvariouscompiled-in--max-stack-size=valsetmaxv8stacksizeEnvironment ';'-separatedlistofdirectoriesprefixedtothemodulesearchpath. Setto1toloadmodulesintheirglobal Setto1todisablecolorsintheREPLationcanbefoundatnodeNode.jsnode其中script.js①是的文件名除了直接運(yùn)行文件外,node--help顯示的使用方法中說明了另一種輸出oWorld的方式:$node-e"console.log('oWorld');"oWorldnodeeloop道在終端下運(yùn)行無參數(shù)的python命令或者使用PythonIDLE打開的s,可以進(jìn)入一個即時求值的運(yùn)行環(huán)境。Node.js也有這樣的功能,運(yùn)行無參數(shù)的node將會啟動一個JavaScript的交互式s:—————————以運(yùn)行。擴(kuò)展名使用.js只是一個約定而已,遵循了JavaScript一貫名習(xí)慣。$ oWorld oReferenceError:consolisnotdefinedatrepl:1:1atREPLServer.eval(repl.js:80:21)atrepl.js:190:20atREPLServer.evalatInterface.<anonymous>(repl.js:182:12)atInterface.emit(events.js:67:17)atInterface._onLine(readline.js:162:10)atInterface._line(readline.js:426:8)atInterface._ttyWrite(readline.js:603:14)atReadStream.<anonymous>(readline.js:82:12)上面例子中undefined就是console.log的返回值。如果你輸入了一個錯誤的指令,REPLCtrl+CNode.jsREPL模式。nodeREPL在應(yīng)用開發(fā)時會給人帶來很大的便利,例如我們可以測試一個包能HTTP前面的oWorld程序?qū)τ谀銇碚f可能太簡單了,因為這個例子幾乎可以在任何語言的教科書上找到對應(yīng)的內(nèi)容,既無聊又乏味,讓我們來點L不一樣的東西,真正感受一下Node.js的所在吧。Node.js是為網(wǎng)絡(luò)而誕生的平臺,但又與ASP、PHP有很大的不同,究竟不同在哪里呢?如果你PHP開發(fā)經(jīng)驗知道在成功PHP之前先要配置一個功能強(qiáng)大而復(fù)雜的HTTP服務(wù)Apache、IIS或Nginx,還需要將PHP配置為HTTP服務(wù)器的模塊,或者使用FastCGI協(xié)議調(diào)用PHP解釋器。這種架構(gòu)是“瀏覽器HTTP服務(wù)器PHP解釋器”的組織方式,而Node.js采用了一種不同的組織方式,如圖3-1所示。我們看到,Node.js將“HTTP服務(wù)器”這一層,直接面向瀏覽器用戶。這種架構(gòu)從某種意義上來說是性的,因而會讓人心存疑慮:Node.js作為HTTP服務(wù)器的效率明。圖3-1Node.jsPHP好了,回歸正題,讓我們創(chuàng)建一個HTTP服務(wù)器吧。建立一個名為app.js的文件,內(nèi)varhttp=require('http');http.createServer(function(req,res){res.writeHead(200,{'Content-Type':'text/html'}); oconsole.log("HTTPserverislisteningatport接下來運(yùn)行nodeapp.js命令,打開瀏覽器,即可看到圖3-2圖3-2Node.jsHTTP服務(wù)用Node.js實現(xiàn)的最簡單的HTTP服務(wù)器就這樣誕生了。這個程序調(diào)用了Node.js提供的http模塊,對所有HTTP請求答復(fù)同樣的內(nèi)容并3000端口。在終端中運(yùn)行這個時,我們會發(fā)現(xiàn)它并不?oWorld一樣結(jié)束后立即退出,而是一直等?Ctrl+C才會結(jié)束。這是因為listen函數(shù)中創(chuàng)建了器,使得Node.js進(jìn)程不會退出循小技巧——使用有P改P直覽結(jié)你odsTTP應(yīng)用時會發(fā)現(xiàn),無論你修改了代碼的哪一部份,都必須終止odejs為ods只有在第一次到某部份時才會去解析腳接而P則總是重新并解析(如果沒有專門的優(yōu)化配置。odjs的這種設(shè)計雖然有利于提高性能,卻不利于開發(fā)調(diào)試,因使用方法很簡單,首先npmsupervisor:$npminstall-g如果你使用的是Linux或Mac,直接鍵入上面令很可能會限錯誤。原因是npm需要把supervisor安裝到系統(tǒng),需要管理員,可以使用sudonpminstall-gsupervisor命令來安裝。$supervisorDEBUG:Runningnode-supervisorwith program'app.js' --watch --extensions'node|js' --exec'node'DEBUG:Startingchildprocesswith'nodeDEBUG:Watchingdirectory'/home/byvoid/.'forchanges.HTTPserverislisteningatport3000.當(dāng)代碼被改動時,運(yùn)行的會被終止,然后重新啟動。在終端中顯示的結(jié)果如下DEBUG:crashingDEBUG:Startingchildprocesswith'nodeapp.js'HTTPserverislisteningatport3000.supervisor這個小工具可以解決開發(fā)中的調(diào)試問異步式I/O與式編Node.js最大的特點就是異步式I/O(或者非阻塞I/O)與緊密結(jié)合的編程模式。這種模式與傳統(tǒng)的同步式I/O線性的編程思路有很大的不同,因為控制流很大程度上要靠和,通常要耗費(fèi)較長的時間,這時操作系統(tǒng)會這個線程的CPU控制權(quán),使其暫停執(zhí)行,同時將資源讓給其他的工作線程,這種線程調(diào)度方式稱為阻塞。當(dāng)I/O操作完畢時,操作系統(tǒng)將這個線程的阻塞狀態(tài)解除,恢復(fù)其對CPUI/O模式就是通I/O(SynchronousI/O)I/O(BlockingIO。相應(yīng)地,異步式I/O(AsynchronousI/O)或非阻塞式I/O(Non-blockingI/O)則針對所有I/O操作不采用阻塞的策略。當(dāng)線程遇到I/O操作時,不會以阻塞的方式等待I/O操作的完模式下,一個線程在執(zhí)行計算操作,這個線程所使用的CPU利用率是100%,I/O以的方式通知。在阻塞模式下,多線程往往能提高系統(tǒng)吞吐量,因為一個線程阻塞CPU資源不被阻塞中的線程浪費(fèi)。而在非阻塞模式下,線程不會被I/O阻塞,在利用CPU。多線程帶來的好處僅僅是在多核CPU的情況下利用的核,而Node.js的單線程也能帶來同樣的好處。這就是為什么Node.js使用了單作,可以分為兩個計算部分和一I/O部分,I/O部分占的時間比計算多得多(通常都是這圖3-3圖3-4單線程驅(qū)動的異步式I/O比傳統(tǒng)的多線程阻塞式I/O究竟好在哪里呢?簡而言之,需要給它分配內(nèi)存、列入調(diào)度,同時程切換的時候還要執(zhí)行內(nèi)存換頁,CPU的緩存被async,表3-1比較了同步式I/O和異步式I/O的特點表3-1I/OI/O同步式I/O(阻塞式 異步式I/O(非阻塞式利用多線程提供吞吐 單線程即可實現(xiàn)高吞吐通過片分割和線程調(diào)度利用多核 通過功能劃分利用多核需要由操作系統(tǒng)調(diào)度多線程使用多核 可以將單進(jìn)程綁定到單核難以充分利用CPU資 可以充分利用CPU資內(nèi)存軌跡大,數(shù)據(jù)局部性 內(nèi)存軌跡小,數(shù)據(jù)局部性符合線性的編程思 不符合傳統(tǒng)編程思讓我們看看在Node.js中如何用異步的方式一個文件,下面是一個例子varfs=fs.readFile('file.txt','utf-8',function(err,data)if{}{;}運(yùn)行的結(jié)果如下Contentsofthe—————————Node.js也提供了同步文件的varfs=vardata=fs.readFileSync('file.txt','utf-8');運(yùn)行的結(jié)果與前面不同,如下所$nodereadfilesync.jsContentsofthefile.同步式文件的方式比較容易理解,將文件名作為參數(shù)傳入fs.readFileSync函數(shù),阻塞等待完成后,將文件的內(nèi)容作為函數(shù)的返回值賦給data變量,接下來控制臺輸出data的值,最后輸出end.。異步式文件就稍微有些了,.先被輸出。要想理解結(jié)果,須先sOe第一個是文件名,第二個是編碼方式,第三個是一個函數(shù),我們稱這個函數(shù)為回調(diào)函數(shù)。JavaScrpt支持的函數(shù)定義方式,譬如我們例子中回調(diào)函數(shù)的定義就是嵌套在etfunctionreadFileCallBack(err,data)if{}{}}varfs=fs.readFile('file.txt','utf-8',readFileCallBack);fs.readFileI/O請求發(fā)送給了操作系統(tǒng),然后立即返回并執(zhí)行后面的語旬,執(zhí)行完以后進(jìn)入循環(huán)。當(dāng)fs接收到I/O請求完成的事件時,循環(huán)會主動調(diào)用回調(diào)函數(shù)以完成后續(xù)工作。因此我們會先看到end.,再看到file.txt文件的內(nèi)容。Node.jsNode.jsAPI都提供了同步和異步版本。Node.jsI/O Node.js所有的異步I/O操作在完成時都會發(fā)送一個到隊列。在開發(fā)者看來,由EventEmitter對象提供。前面提到的fs.readFilehttp.createServer的回調(diào)varEventEmitter=varevent=newevent.on('some_event',{console.log('some_event{},運(yùn)行這段代碼,1some_eventoccured.event對象了some_event的一個器,然后我們通過setTimeout在1000毫秒以后event對象發(fā)送some_event,此時會調(diào)用some_event的器。4.3.1節(jié)中詳細(xì)討論EventEmitter對象的用法。Node.js的循環(huán)機(jī)Node.js在什么時候會進(jìn)入循環(huán)呢?答案是Node.js程序由循環(huán)開始,到循環(huán)結(jié)束,所有的邏輯都是的回調(diào)函數(shù),所以Node.js始終在循環(huán)中,程序就是(it回,查的到。3了的。EventEmitter封裝。libev循環(huán)的每一次迭代,在Node.js中就是一次Tick,libev不斷檢查是否有活動的、可供檢測的器,直到檢測不到時才退出循環(huán),進(jìn)程結(jié)束。圖3-5循模塊和(due(kae是ds最重要的支柱。開發(fā)一個具有一定規(guī)模的程這種方式而誕生的。在瀏覽器vrt中,模塊的拆分和組合通常使用ML的t來實現(xiàn)。odjs提供了e用,都于Node.js的模塊和包機(jī)制的實現(xiàn)參照了CommonJS的標(biāo)準(zhǔn),但并未完全遵循。不過兩者的區(qū)別并不大,一般來說你大可不必?fù)?dān)心,只有當(dāng)你試圖制作一個除了支持Node.js之外還要支持其他平臺的模塊或包的時候才需要仔細(xì)研究。通常,兩者沒有直接的地方。odejs的模塊和包相提并論,因為模塊和包是沒有本質(zhì)區(qū)別的,兩個概念也時?;煊?。如果要辨析,那么可以把包理解成是實現(xiàn)了某個功能模塊的集合,用于發(fā)布和。對使用者來說,模塊和包的區(qū)別是透明的,因此經(jīng)常不作區(qū)分。本節(jié)中我們會詳細(xì)介紹:0什么是模塊0如何創(chuàng)建并加載模0如何創(chuàng)建一個包0如何使用包管理器模塊 應(yīng)用程序的基本組成部分,文件和模塊是一一對應(yīng)的。換言之,一varhttprequire('http'),是Node.js的一個模塊,其內(nèi)部是用C++實現(xiàn)的,外部用JavaScript封裝。我們通介紹了什么是模塊之后,下面我們來看看如何創(chuàng)建并加載它創(chuàng)建模Node.js中,創(chuàng)建一個模塊非常簡單,因為一個文件就是一個模塊,我們要關(guān)注的問題僅僅在于如何在其他文件中獲取這個模塊。Node.js提供了exports和require兩個對象,其中exports是模塊公開的接口,require用于從外部獲取一個模塊的接口,即所獲取模塊的exports對象。module.jsvarexports.setName={name=exports.sayo={console.log('o'+在同 下創(chuàng)建getmodule.js,內(nèi)容是varmyModule= 運(yùn)行nodegetmodule.js,結(jié)果是o在以上示例中,module.jsexports對象把setNamesayo作為模塊的訪問接口,在getmodule.js中通過require('./module')加載這個模塊,?后就可以?接module.js中exports對象的成員函數(shù)了。這種接口封裝方式比許多語言要簡潔得多,同時也不失優(yōu)雅,未引入語義的特性,符合傳統(tǒng)的編程邏輯。在這個基礎(chǔ)上,我們可以構(gòu)建大型的應(yīng)用程序,npm提供的上萬個模單次加上面這個例子有點類似于創(chuàng)建一個對象,但實際上和對象又有本質(zhì)的區(qū)別,因為我們在getmodule.js的基礎(chǔ)上稍作修改: o1=require('./module'); o2=require('./module');o2.setName('BYVoid2');o1.say運(yùn)行后發(fā)現(xiàn)輸出結(jié)果是oBYVoid2,這是因為變量o1和o2指向的是同一個實例,因此o1.setName的結(jié)果被o2.setName覆蓋,最終輸出結(jié)果是有時候我們只是想把一個對象封裝到模塊中,例 o()varthis.setName=function{name=this.sayo=function{console.log('o'+exports.o=此時我們在其他文件中需要通過require('./singleobject').o來獲取//functiono()varthis.setName={name=this.sayo={console.log('o'+module.exports=這樣就可以直接獲得這個//getvaro=require('./o=newo();注意模塊接口的唯一變化是使用module.exports=o代替了exports.o=o。在外部該模塊時,其接口對象就是要輸出的o對象本身,而不是原先的事實上,exports本身僅僅是一個普通的空對象,即{},它專門用來接口,本所以可以用其他東西來代替,譬如我們上面例子中的o對象?!?閉包是函數(shù)式編程語言的常見特性,具體說明見本書附錄Aexportsmodule.exports它本身會在模塊執(zhí)行結(jié)束后釋放,但modulemodule.exports未改變接口包是在模塊基礎(chǔ)上更深一步的抽象,Node.jsC/C+Java/.Net據(jù)CommonJS規(guī)范實現(xiàn)了包機(jī)制,開發(fā)了npm來解決包的發(fā)布和獲取需求。Node.js的包是一個,其中包含一個JSON格式的包說明文件package.json。嚴(yán)格符合CommonJS規(guī)范的包應(yīng)該具備以下特征:0package.json必須在包的頂 0二進(jìn)制文件應(yīng)該在 0JavaScript代碼應(yīng)該在 下0單元測試應(yīng)該在 Node.js對包的要求并沒有這么嚴(yán)格,只要頂層 下有package.json,并符合一些規(guī)范即可。當(dāng)然為了提高兼容性,我們還是建議你在制作包的時候,嚴(yán)格遵守CommonJS 作為文件夾的模somepackage的文件夾,在其中創(chuàng)建index.js,內(nèi)容如下: o={ 然后在somepackage之外建立getpackage.js,內(nèi)容如下varsomePackage=require('./somepackage'); 面例子中的somepackage文件夾下,我們創(chuàng)建一個叫做package.json的文件,內(nèi)容如{"main":}然后將index.js重命名為interface.js并放入lib子文件夾下。以同樣的方式再次調(diào)用這個Node.jspackage.json文件的main字段,將其作為包的接口模塊,如果package.json或main字段不存在,會嘗試index.jsindex.node作package.jsonCommonJSpackage.json文Oname:包的名稱,必須是唯一的,由小寫英文字母、數(shù)字和下劃線組成,不能包含OdescriptionOversion:符合語義化版本識別① Ocontributors:貢獻(xiàn)者數(shù)組,格式與maintainers相同。包的作者應(yīng)該是貢獻(xiàn)者Obugs:提交bug的地址,可以是或者電子郵件地址Olicenses:證數(shù)組,每個元素要包含type(證的名稱)和url(到url(倉庫的地址)和path(相對于倉庫的路徑,可選)字段。—————————下面是一個完全符合CommonJS規(guī)范的package.json示例:{"name":elementsofaCommonJSpackage.","version":"0.7.0", ":["maintainers":{"name":"Bill ": }"contributors":{"name":"web": }"bugs":"mail": "web": "licenses":{"type":"url":"}"repositories":{"type":"url": }{"webkit":"1.2","ssl":{"gnutls":["1.0","openssl":}}}Node.js包管理器,即npm是Node.js提供的包管理工具①,它已經(jīng)成了Node.js包的標(biāo)準(zhǔn)發(fā)布平臺,用于Node.js包的發(fā)布、、依賴控制。npm提供了命令行工具,使你可獲取一個使用npm安裝包令格式為npm[install/i]$npminstall或者$npmi隨后你會看到以下安裝信npmhttpGETnpmhttp304npmhttpGETnpmhttpGETnpmhttpGETnpmhttpGETnpmhttpnpmhttpnpmhttp200npmhttpGETnpmhttpGETnpmhttpnpmhttpnpmhttp200
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 汽車銷售入股合同范本
- 白糖批發(fā)銷售合同范本
- 雙門轎跑車產(chǎn)業(yè)分析報告
- 單位采購供貨合同范例
- 單包木工合同范本
- 加盟產(chǎn)生費(fèi)用合同范本
- 物探工題庫(含參考答案)
- 汽車電工電子應(yīng)用試題
- 個人工作任務(wù)總結(jié)
- 廚具清洗維修合同范例
- 2025年AM5裝置Modbus通訊規(guī)約說明V2.0-20171127
- 2025年昆明市公安局招考文職人員高頻重點提升(共500題)附帶答案詳解
- 建筑制圖與 CAD-識讀外墻身詳16課件講解
- 河北省高等職業(yè)院校技能大賽關(guān)務(wù)實務(wù)賽項參考試題及答案
- 黔源電力筆試內(nèi)容
- 草坪露營地規(guī)劃設(shè)計
- 運(yùn)灰安全管理制度模版(2篇)
- 2024解析:第四章光現(xiàn)象-講核心(解析版)
- 2024解析:第十九章生活用電-講核心(解析版)
- 2024年湖南省公務(wù)員錄用考試《行測》真題及答案解析
- 慢性阻塞性肺疾病急性加重圍出院期管理與隨訪指南(2024年版)
評論
0/150
提交評論