轉自Di Wu的博客
利用 Node.js 開發(fā)是一個非常有趣,和令人滿足的過程, 他有3萬多個模塊可以選擇使用,并且所有的模塊可以非常容易的集成入現(xiàn)有的應用之中.
無論如何,對于一些剛開始使用Node.js 開發(fā)的的人來說, 很容易碰壁,在這個文章中,我會提到在你學習過程中遇到的問題.
貼士 1: 在開發(fā)環(huán)境使用 nodemon, 在生產(chǎn)環(huán)境使用pm2
當你第一次開發(fā)Node.js應用的時候, 其中一件事情就是一次又一次的運行[file].js 就和揭傷疤一樣. 當我第一次開發(fā)的node app時候,這個讓我感到異常挫敗和痛苦, 尤其是每當我修改很小東西的時候需要 control+c
幸運的是我發(fā)現(xiàn)了一個非常棒的工具 Nodemon. 你可以利用以下的命令來安裝
- npm install -g nodemon
Nodemon 是一個令人驚嘆的工具, 當你全局安裝他以后, 可以通過 nodemon [file].js 來啟動你的node.js scripts,它會告訴nodemon來監(jiān)視你的script和scripts的所有變化, 這樣的Node.js開發(fā)方式非常震撼以及讓大大提高開發(fā)速度.
那么,生產(chǎn)環(huán)境又如何, 除非你用了 heroku, Nodejitsu 或者其他一些好的 Node.js 平臺(也許他們有類似的功能), 但是碰巧你用了EC2 或者一些其他的云平臺來運行你的Node.js app, 你如何能然保證這是一個始終運行的Node.js app?
案就是
PM2, PM2 是一個類似于Nodemon的工具,不同之處在于它用于生產(chǎn)環(huán)境, 和Nodemon相似的地方在于他會監(jiān)控你的app的任何修改或者重新部署,但是有更好的一面, PM2 在遭遇到崩潰的時候,他會正確重啟你的app.
PM2的優(yōu)勝之處在于當你要將app需要多核處理的時候,PM2內部集成的負載均衡可以讓你很容易的去指定運行多少個實例.
- pm2 start app.js -i max
-i 參數(shù)目的是指定運行多少個實例,在這個例子中 PM2 使用了一個常量 max 來擴展你的app運轉到你最大的核數(shù),不要忘記Node 平時只會運行在單核!
貼士 2: Async 或者 Q
當你專注于寫了更多的node.js apps的時候,你肯定領略了什么是回調地獄. 如果你還不知道,這里有一個例子:
- function register(name, password, cb){
- checkIfNameExists(name, function(err, result){
- if(err){
- return cb(“error”);
- }
- checkIfPasswordGood(password, function(err, result){
- if(err){
- return cb(“error”);
- }
-
- createAccount(name,password, function(err,result){
- if(err){
- return cb(“error”);
- }
- createBlog(name, function(err, result){
- sendEmail(name, function(err, result){
- callback(result);
- });
- });
- });
- });
- });
- }
這顯然不是一個有用或者令人折服的代碼, 反而進入一種回調地獄般兩難的境地,是你的話將如何避免?
一個簡單的辦法是使用events, 但是我個人不建議這么做,因為使用events來調用只有一個用途的私有方法,足以令人受挫
所以你該怎么做? 這里有兩個編譯好的模塊, async.js 和 Q, 他們兩個都可以防止落入回調地獄
Async.js 或者 ‘a(chǎn)sync’ 讓你可以容易的執(zhí)行一些連續(xù)或者平行的任務,在不依賴一個又一個的嵌套循環(huán)前提下.
下面是一些來自Async的readme,寫明了他支持的模式, 如需獲取全部的支持方式請去他們的github主頁查看.
- async.map([‘file1',’file2',’file3'], fs.stat, function(err, results){
- // results is now an array of stats for each file
- });
-
- async.filter([‘file1',’file2',’file3'], fs.exists, function(results){
- // results now equals an array of the existing files
- );
-
- async.parallel([
- function(){ … },
- function(){ … }
- ], callback);
-
- async.series([
- function(){ … },
- function(){ … }
- ]);
-
- async.waterfall([
- function(callback){
- callback(null, ‘one’, ‘two’);
- },
- function(arg1, arg2, callback){
- callback(null, ‘three’);
- },
- function(arg1, callback){
- // arg1 now equals ‘three’
- callback(null, ‘done’);
- }
- ], function (err, result) {
- // result now equals ‘done’
- );
如果我們用async的waterfall來修改之前的例子,結果將更加容易閱讀, 再也不用讓你的代碼看起來像一個死亡金字塔.
另一個重要的庫叫做
Q. 這個庫是一個暴漏promises的概念, Promise 是一個含有’promise’方法的返回對象,他提供了一個最終的返回值,非常優(yōu)雅的將javascripts的異步和node.js緊密聯(lián)系在一起.
- For example, taken from Q’s repo page.
- promiseMeSomething()
- .then(function (value) {
- }, function (reason) {
- });
這個 promise me 方法 正確返回了一個對象, 對象將在傳入value的時候調用這個方法當,并且他提供了一個額外的callback來處理失敗后的返回值
這是一個非常有條理的方式來避免回調地獄,如果你重寫我們之前的那個例子,你可以非常容易的讓這些函數(shù)正確被調用并執(zhí)行.
就和我之前說的一樣, 我很不愿創(chuàng)建只有一個用途的一堆功能,相反的在’then’之后傳入一個方法名,僅僅創(chuàng)建了一個匿名的內部功能和傳遞,當然了選擇權始終在你手里.
總的來說,當你落入回調地獄的時候,是時候去看看 async.js或者Q吧.
貼士 3: 輕松調試 Node.js apps
如果你從一個IDE重度集成的語言比如java 或者C# 轉來調試Node.js, 你一定會感到很困擾, 大部分新加入node的開發(fā)者采用了’flow’的調試模式,從這一刻開始你最好的朋友就是console.log
但是依然有更常見的調試方式來代替, Node.js 內置了一個調試器你可以稱為 node debug, 不過我更喜歡的 node-inspector
他們的github說 “Node Inspector 是一個使用Blink Developer Tools (以前稱為WebKit Web Inspector)node.js調試器的界面,”
簡而言之,node-inspector 可以讓你用任何你想用的編輯器和chrome web tools來調試你的應用,這是多么的性感.
Node-inspector 可以讓你做一些非常酷的事情,比如實時修改,單步調試,注入以及一堆其他非常酷的東西.
讓我們來根據(jù)指示一步一步安裝
貼士 4: Nodefly
一旦你有你的應用程序正常運行,你可能會問自己,你怎么可以監(jiān)視它的性能和配置文件,以確保您的應用程序運行在最佳的速度。最簡單的答案是一個偉大的服務,我稱為Nodefly。
用簡單的一行代碼Nodefly開始監(jiān)視你的應用程序內存泄漏,測量redis用了多久,mongo查詢和一堆其他很酷的東西。
貼士 5: 利用NPM進行模塊管理
Node做最常見的事情之一是通過NPM安裝軟件包。Node有一個驚人的包管理器安裝所有指定在你的package.json的manifest文件中的模塊。然而,所有初學者都會碰上保持的package.json文件中您所使用的所有的模塊都是最新版。
這似乎是一個痛苦的過程,總是打開的package.json來更新新模塊的依賴,但許多人不知道的是npm會為你做這個!
非常簡單運行 npm install - save module_name 然后 npm將自動更新你的package.json 包含正確的模塊和版本,
- npm install - save module_name
貼士 6: 不要檢查node_modules 文件夾
雖然我們的話題一直是modules和npm,但是并不是不是很多人都知道,你不應該提交node_modules文件夾。這背后最大的原因是,沒有必要提交這個文件夾。只要有人下載你的代碼,他們可通過運行NPM來安裝和下載所有需要的模塊。
您可能會說,它是不是一個大問題,如果檢查node_modules,但是,如果下載代碼的人使用了和你編譯modules不一樣的操作系統(tǒng)的來安裝通過NPM?你的應用程序將會崩潰,下載代碼的人將不知道為什么會如此!
舉個例子 bcrypt 以及 sentimental 如果當在您安裝在主機系統(tǒng)上編譯他們,因為他們用了本地C語言組件來編譯.
避免檢查node_modules文件夾的方式是加入.gitignore
- // .gitignore node_modules/*
貼士 7: 別忘記返回
初學者經(jīng)常犯一個很常識的錯誤,就是忘記callback后的返回值,雖然有些時候,這沒有影響,有很多時候,你會遇到奇怪的問題,因為你的回調被調用兩次。
讓我們看一個簡單的例子
- function do(err,result, callback){
- if(err){
- callback(“error”);
- }
- callback(“good”);
- }
乍一看,這個片段是有道理的。如果有錯誤,在回調中發(fā)送“錯誤。如果不發(fā)送return,調用callaback后這個函數(shù)不會停下來。它只是將移動到調用回callback(“good”)。
這樣做在長期和復雜的代碼行里面會節(jié)省幾個小時的調試。