前言javascript
這裏主要說一下以前使用Nodejs開發踩過的坑,只說坑不填坑,那就是赤裸地耍流氓,文中有大量的說明及填坑方法,瞭解的看官能夠直接跳過。css
PS:說實話,Nodejs的坑確實蠻多的;可是上手簡單,擴展包衆多,讓你的開發變得十分簡易。html
1.代碼精簡java
儘可能使用精簡的代碼,Nodejs 代碼處理速度是異常慢的,不如其餘主流語言,甚至不如python,使用精簡代碼也是對本身能力的提高與考驗。咱們在作卡地亞商城項目時,對方工程師要求同一函數內,同一變量不能夠出現三次(loop中僅算做一次)。代碼精簡了,就會變得漂亮,查找問題也變得容易,也方便後面的工程師接手處理。node
不建議在Nodejs代碼中再套用其餘框架,例如coffeescript,Node與Coffee會報不一樣的錯誤。python
2.精確版本號web
這個坑,估計不少人都踩過,開發環境與實際環境不一致。同事開發一個模塊,本地聯調是沒問題的,可是到server端後,根本沒法啓動,找了一圈,最後發現同事本地開發使用的是Node的化石版,就是這麼個小疏忽,讓咱們浪費了一上午去找緣由。redis
補充一些Node版本管理的知識:編程
* //任意版本 1.1.0 //指定版本 ~1.1.0 //>=1.1.0 && < 1.2.0 ^1.1.0 //>=1.1.0 && < 2.0.0
3.單元測試json
必定要寫單元測試用例,嘗試本地運行,測試成功後再上傳至服務器,有幾回修改完代碼(簡單幾行)覺得怎麼可能出問題,結果一重啓服務就掛了,可能少個括號之類的。
Mocha是我最長使用的單元測試工具:
基本概念:
describe()測試區塊,能夠多層鑲套。
it()測試用例,一個測試區塊能夠包含多個測試用例。
測試鉤子:
before() 在本區塊全部測試用例執行以前執行。
after() 在本區塊全部測試用例執行以後執行。
beforeEach() 在本區塊每一個測試用例以前執行。
afterEach() 在本區塊每一個測試用例以後執行。
斷言:
chai ;Mocha自己沒斷言,chai能夠做爲它的斷言庫。chai-as-promise 這個庫支持promise。
用例管理:
only()測試區塊與測試用例都支持only方法,只運行修飾的測試區塊或用例。
skip()測試區塊與測試用例都支持skip方法,會跳過修飾的測試區塊或用例。
only與skip共用時,only會忽略掉skip。
異步調用:
done(),測試方法異步完成後,被調用。一個it測試實例中只能有一個done()。
例:
var assert = require('chai').assert; function add() { return Array.prototype.slice.call(arguments).reduce(function (prev, curr) { return prev + curr; }, 0); } describe('add()', function () { var tests = [ { args: [1, 2], expected: 3 }, { args: [1, 2, 3], expected: 6 } ]; tests.forEach(function (test) { it('test adds ' + test.args.length + ' args', function () { var res = add.apply(null, test.args); assert.equal(res, test.expected); }); }); });
4.debug
開發避免不了調試debug,不少人喜歡使用console.log()進行調試,這個確實蠻好用的,可是調式後如何處理console.log() 卻成爲了老大難的問題,註釋吧,會多出不少無用的代碼,刪掉吧,後面可能還會使用到。
這裏,我推薦使用debug模塊爲例:
var debug = require('debug')('myapp:main'); debug('如今的時間是 %s' , new Date());
開啓debug模式(在cmd上輸入): set debug = myapp:main
而後輸入要執行的文件:node app.js
返回:myapp:main 如今的時間是 2018-05-03 18:25:30
關閉debug模式: set debug = null
5.配置文件書寫
每一個工程下都要創建一個配置文件,如config.js,而不是寫死在程序裏,記住接手你工做的人,是不懂你的編程邏輯的人,因此到時候你要告訴對方哪些是可配哪些是不可配,後面你會很是麻煩。
配置文件例:
{ "app": 3000, "mongo": { "host": "localhost", "port": 27017 }, "redis": { "host": "localhost", "port": 6379 } ... }
6.避免使用同步代碼
Nodejs的一個顯著特徵:從上到下的設計都是爲了實現異步。文件操做就有同步和異步的版本,即便使用邏輯來控制同步方法,但仍是有可能不注意地用到阻塞外部的函數庫。這樣作,對性能影響極大。
//好的書寫方式 fs.writeFile('message.txt','Hello Node',function(err) { console.log("It's saved and the server remains responsive!"); }); //壞的書寫方式(影響性能) fs.writeFileSync('message.txt', 'Hello Node'); console.log("It's saved, but you just blocked ALL requests!");
7.不要讓靜態資源使用Nodejs
對於css和圖片等靜態資源,用標準的webserver而不是Nodejs。咱們使用的是CDN來存儲靜態資源。
好處:
1)減小nodejs服務器的負載。
2)CDN可讓靜態內容在離用戶較近的服務器上傳遞,減小等待時間。
8.在客戶端渲染
咱們比較一下在客戶端渲染和在服務端渲染的區別:
服務端渲染
<!DOCTYPE html> <html> <head> <title>服務端渲染</title> </head> <body> <div> py1988! </div> </body> </html>
客戶端渲染
<!DOCTYPE html> <html> <head> <title>客戶端渲染</title> </head> <body> <div> <%= name %>! </div> </body> </html>
javascript文本能緩存在瀏覽器或者本地,全部初始加載之後,惟一要發送給客戶端的就是json,這是最有效的,極大減小Nodejs server的負載量。
9.並行化
試着讓全部的阻塞操做並行化,這將減小阻塞操做的等待時間,爲了保持回調和錯誤處理得乾淨,咱們須要使用一些監控工具。
10.儘可能使用二進制模塊
使用二進制模塊取代javascript模塊(儘可能);如此性能會提高一大截。
var crypto = require('crypto'); var hash = crypto.createHmac("sha1",key).update(signatureBase).digest("base64");
特殊:使用V8 javascript 取代客戶端庫
許多javascript庫都是爲了在瀏覽器上使用而建立的:例 一些瀏覽器支持 forEach,map和reduce這樣的函數,但有些瀏覽器不支持。
V8 javascript 引擎支持Node.js實現ECMA-262第五版中指定的ECMAScript。直接用標準的V8 JavaScript函數替代客戶端庫,你會發現性能獲得顯著的提升。