天天看點

Node.js / JavaScript後端開發指引

這是一篇關于後端 JavaScript 開發的指引,如果你對 JavaScript 的認識仍然停留在前端開發的話,你需要更新自己的知識體系了。

<a href="http://blog.eood.cn/nodejs_dev#npm">用 NPM 來做項目管理和包維護</a>

<a href="http://blog.eood.cn/nodejs_dev#grunt">用 Grunt 來做代碼格式修整、Lint 和其他自動化任務</a>

<a href="http://blog.eood.cn/nodejs_dev#coffeescript">用 CoffeeScript 方言寫更友好的 JavaScript</a>

<a href="http://blog.eood.cn/nodejs_dev#libs">必不可少的幾個庫</a>

<a href="http://blog.eood.cn/nodejs_dev#underscore">underscore</a>

<a href="http://blog.eood.cn/nodejs_dev#async">Async</a>

<a href="http://blog.eood.cn/nodejs_dev#addons">開發 C++ addons 增強和擴充 Node.js</a>

<a href="http://blog.eood.cn/nodejs_dev#config">Node.js 配置管理方式</a>

<a href="http://blog.eood.cn/nodejs_dev#service">開發内部 Service 推薦的部件</a>

<a href="http://blog.eood.cn/nodejs_dev#forever">Forever: Daemon 管理工具</a>

<a href="http://blog.eood.cn/nodejs_dev#cluster">Node.js Cluster</a>

<a href="http://blog.eood.cn/nodejs_dev#faq">JavaScript 開發常見問題</a>

<a href="http://blog.eood.cn/nodejs_dev#pass">JavaScript 是傳值還是傳引用?</a>

<a href="http://blog.eood.cn/nodejs_dev#gdb">如何用 GDB 調試自己開發的 Node.js C++ addons?</a>

<a href="http://blog.eood.cn/nodejs_dev#catch">如何捕獲 uncaughtException 并列印詳細錯誤資訊?</a>

<a href="http://blog.eood.cn/nodejs_dev#shutdown">如何優雅結束程序?</a>

<a href="http://blog.eood.cn/nodejs_dev#array">如何選擇使用 Array 和 Object?</a>

<a href="http://blog.eood.cn/nodejs_dev#sla">如何聚合多個後端服務并提供 SLA ?</a>

<a href="http://blog.eood.cn/nodejs_dev#nexttick">什麼時候使用 process.nextTick() ?</a>

<a href="http://blog.eood.cn/nodejs_dev#ref">更多相關參考</a>

Web 開發架構從以前流行的 LAMP/LEMP  架構逐漸轉移到 Ruby on Rails 和 Python Django 架構之上。但最近有另外幾種的架構變得成熟了:比如 Golang, Clojure/leiningen,  Node.js 。這三者之中我更關注 Node.js。原因是它的生态更加完善。是以最近的幾個項目都是用它來實作的。Node.js 既适合做後端 API 的粘合,也适合給終端使用者提供 API 。

Node.js 的每個項目都應該有一個 package.json 配置檔案。其中包含了這個項目或者庫的資訊和所依賴的庫。一個相對完成的 package.json 檔案像這樣:

這個檔案可以在你的項目目錄下執行 npm init 來按指引建立。注意其中的 scripts 部分,這裡可以建立很多自定義指令。比如如此配置之後,npm start 會執行 forever start app.js 指令。

Grunt 是一個指令行任務自動化工具。它包含了很多有用的插件。可以實作代碼美化、自動化部署、自動生成 sprit、自動建立項目模闆、自動壓縮前端代碼、自動編譯 coffescript 等等你能想到的任務。假如你找不到自己需要的功能,還可以自己開發 Grunt 插件來實作。它的配置檔案是位于項目根目錄的 grunt.js 。一般項目都需要的功能是代碼美化和 Lint,配置檔案象這樣:

添加了配置檔案之後可以在項目目錄運作 grunt 指令自動執行任務串。grunt beautify 可以執行子任務。

CoffeeScript 提供了類似于 Ruby 的文法,簡化了 JavaScript 的書寫,簡化了 JavaScript 中實作類和類的繼承的實作。你不必再自己繁瑣得通過 prototype 和 constructor,call,apply 實作類的繼承。 無論用 VIM 還是 Sublime Text 都可以找到對應的實時轉換工具,在寫 CoffeeScript 的同時就能看到對應的 JavaScript。

underscore 是寫 JavaScript 必不可少的庫。提供了一些非常常用的方法,這些方法不僅使用友善,而且提高了代碼的可讀性。:

用 _.each 代替 for 循環,比如:

可以改寫為:

其他常用的方法還有:

_.map 用來對數組元素進行批量轉換

_.reduce 用來将數組元素合并為結果

_.pluck 用來取對象數組中的子元素,傳回包含對應子元素的新數組

_.filter 用來有選擇性的取數組中的某些值,傳回包含符合條件的值的新數組

_.mixin 用來增加自定義函數

_.chain 用來實作函數式程式設計:

Async.js 對常用的流程控制模式進行了封裝,比如并行處理、Pipeline等等:

async.parallel 并行處理,整體等待最慢的函數傳回,常用作多個後端請求的聚合或者并行處理:

async.waterfall 可以用來将大量嵌套的函數順序執行,前一個函數的結果作為下一個函數的參數。用它之後你的代碼裡将不會再出現過深的 callback 嵌套:

這意味着你不必擔心某些邏輯的性能,也不必擔心和其他架構的繼承。因為所有語言或者開發棧都會提供 C/C++ 的接口。

有兩種配置方式,config.js 或者 config.json 假如以 config.js 作為配置檔案:

如果以 config.json 作為配置檔案:

程序統計資訊,比如 uptime, memory usage, heap size, connection number, 處理的請求數量等等。這樣便于和監控系統對接

RESTful apis,推薦以 RESTful JSON 格式作為内部通信協定,這其實對大部分應用完全足夠,而且容易調試。

配置檔案。将可能會發生變化的變量放到配置檔案裡。

Service Level Agreement。比如超過 100ms 的請求報錯而不是繼續等待傳回資訊。

既然 Node.js 是長時間運作的背景程序,缺不了程序管理工具。Forever 就是為了實作對 Node.js 的 daemon 程序進行管理的工具。常用指令:

forever start app.js 啟動程序

forever restart app.js 重新開機程序

forever list 列出背景程序,并且列出 log 檔案,可以友善的及時檢視 log 檔案内容。

Node.js Cluster 是為了利用多核 CPU 的計算能力, 并且子程序可以共用同一個端口:

簡單說:如果參數為一個對象則為傳引用,如果參數為變量或者函數則為傳值。

gdb –args nodejs script.js

在程序級别捕獲異常:

Node.js 中對接收的 POSIX 信号做自定義操作很友善,進行程序結束前的清理工作:

對于清單類的資訊,比如使用者清單推薦使用 Object 而不是 Array:

用 Node.js 可以非常簡單的實作對傳回所用時間進行控制。比如在之前例子代碼 async.parallel 的請求中設定逾時定時器。對多個處理程序并發請求取其中時間最短的結果,這樣可以保證傳回時間都保持很短。

重量使用 CPU 的函數中釋放 CPU 給其他任務

将執行放到下一個 tick ,等待初始化

<a href="http://nodejs.org/">http://nodejs.org/</a>

<a href="https://npmjs.org/">https://npmjs.org/</a>

<a href="http://coffeescript.org/">http://coffeescript.org/</a>

<a href="http://underscorejs.org/">http://underscorejs.org/</a>

<a href="http://nodejs.org/api/addons.html">http://nodejs.org/api/addons.html</a>

<a href="http://expressjs.com/">http://expressjs.com/</a>

<a href="https://github.com/caolan/async">https://github.com/caolan/async</a>

<a href="http://howtonode.org/understanding-process-next-tick">http://howtonode.org/understanding-process-next-tick</a>

<a href="http://book.mixu.net/ch7.html">http://book.mixu.net/ch7.html</a>

<a href="http://gruntjs.com/">http://gruntjs.com/</a>