歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 2016 年,新 Node 項目注意點

2016 年,新 Node 項目注意點

日期:2017/3/1 9:19:04   编辑:Linux編程

正文

2016年開發 Node 項目,會有什麼不一樣嗎?! 當然隨著語言,工具,運行環境,開發方式的不斷變化,你的 Node 項目當然也需要不斷的與時俱進,那麼我們就依次來看看需要注意哪些問題吧。

目錄

  • 現在開始使用 ES2015
  • 異步函數支持回調慣例和Promise新寫法
  • 異步模式
  • 錯誤處理
  • 使用標准的 JavaScript 代碼風格
  • Web 應用開發的十二條軍規
  • 始終用 npm init 開始新項目
  • 文件名始終小寫
  • 智能的 .npmrc 和正確的版本管理做法
  • 及時更新依賴
  • 選擇合適的數據庫
  • 監控你的應用程序
  • 使用構建系統
  • NPM 生命周期鉤子
  • 管好垃圾回收
  • 使用長期支持的 Node.js 版本
  • 使用語義化的版本號
  • 持續學習和跟上潮流

現在開始使用 ES2015

箭頭函數
模板字符串
rest參數,擴展運算符(spread),函數默認值
變量的解構賦值
generator 和 promises
maps,sets 和 symbols

這些新語法大部分都被 Node.js V4 支持(參考)[https://nodejs.org/en/docs/es6/]
在服務器端的推薦使用新的 node 解釋器支持的語法,或者可以用babel作為compile層(具體做法參考腳手架)

// 從 express's req.query 解構 特定參數 ?page=2&size=10&word=測試

let {page, size, word} = req.query;

異步函數支持回調慣例和Promise新寫法

過去,當Promise沒有成為Node默認搭載的語法時,推薦模塊通過導出 error-first callback 的接口形式。但是現在通常需要支持兩種形式:

const fs = require('fs')

function readPackage(callback=noop) {
  return new Promise((resolve, reject)=>{
    fs.readFile('./package.json', (err, data)=>{
      if(err) {
        reject(err)
        return callback(err)
      }
      resolve(data)
      return callback(null, data)
    })
  })
}

異步模式

過去很長時間,在 node 中一般有兩種方式來管理異步流:callback回調和 streams 流
前者可以用輔助我們異步操作的 async 類庫
後者可以用through, bl or highland 這些類庫
但是隨著 es6的 generator和promise的到來,甚至es7的 await/async 內建關鍵字的到來,情況變了。 詳細請看 異步JavaScript的演進

錯誤處理

完善合理的錯誤處理讓你的服務更加強健。知道何時crash,然後是僅僅catch後忽略,還是記下調用棧打入log後重試,甚至是需要重啟?
我們通常需要區別對待 programmer error, operational errors:
前者直接重啟(事實上在開發階段就該發現,並且線上通過 logger 定位),因為程序員寫的bug,如果不及時重啟會導致應用的狀態難以推演,從而發生更多更大的問題
而後者,通常不是bug,而是沒有考慮全的case。如外部請求超時了,外部依賴的數據庫連不上了,甚至所在運行的機器磁盤寫滿了,要訪問寫入的文件暫時不存在了。這些case一般需要在程序裡加上特定的fallback/polyfill 來處理。如對於超時的重試幾次,對於不存在的文件先試著創建新文件,對於總是塞滿磁盤的log,通過logstash和logrotate去處理。

回調中的錯誤處理

error-first 約定的callback,始終記得在函數開始檢查第一個err是否存在,然後進行合適的處理(當然也可以通過 next(e) 傳入到調用棧的最後統一處理)

Promise中的錯誤處理

始終記得在 promise 調用鏈的最後加上 catch 來處理異常

使用標准的 JavaScript 代碼風格

過去我們使用 jslint, jshint, jscs 來作為我們的代碼風格檢查工具,但是隨著 es6 的流行,還有一些新的習慣的養成,我們推薦使用 eslint 工具,同時配合 eslint-plugin-standard 插件

{
  "plugins": [
    "standard"
  ],
}

Web 應用開發的十二條軍規

來自於 Rails 社區的血淚經驗,但是大部分也是適用於我們Node項目 (一些實踐可能在新的docker部署下會有小調整)

  • 一份基准代碼Codebase,多份部署deploy
  • 顯示聲明和隔離依賴
  • 在配置放在環境中
  • 把外部後端服務當做附加資源
  • 嚴格分離構建和運行環境
  • 以一個或多個無狀態進程運行應用
  • 通過端口綁定(Port binding)來提供服務
  • 通過進程模型進行擴展
  • 快速啟動和優雅終止可最大化健壯性
  • 盡可能的保持開發,預發布,線上環境相同
  • 把日志當作事件流
  • 後台管理任務當作一次性進程運行

始終用 npm init 開始新項目

通過 npm init 來初始化你的node項目,通過promt 確定你的項目名稱,開發者信息等(當然你可以通過 --yes 旗標來跳過)
Tip: 主要你應該總是顯示指名你的node engines 版本(node -v),確保你的開發環境,測試環境和線上環境是用同一版本的 node.

{
    "engines": {
        "node": "4.2.1"
    }
}

文件名始終小寫

因為在 OSX 和 Windows 系統中,MyClass.js 和 myclass.js 沒有任何區別,Linux 則會區分。所以為了你寫的代碼在不同操作系統是可移植的(在使用 require 來引入模塊確保語句是一致明確的),所以始終保持小寫 - my-class.js

智能的.npmrc 和正確的版本管理做法

默認上, npm 在安裝新的依賴的modules,默認不會加入到package.json中。同時,modules的版本號不是嚴格鎖死的(^尖角號來確保大版本保持一致)這樣會造成一些問題,如在發布時才發現沒有把依賴寫入到package.json中,造成線上缺少必要的模塊,線上部署發現用的不是相同的modules,導致莫名其妙的問題和大量的depricated warning警告。

所以安裝新依賴推薦這樣的寫法:npm install foobar --save --save-exact
或者寫入.npmrc 這樣下次 npm install 就不會犯錯啦

$ npm config set save=true
$ npm config set save-exact=true
$ cat ~/.npmrc

當然啦,如果如果希望更靈活的依賴控制,可以通過 npm shrinkwrap 命令生成 npm-shrinkwrap.json 加入到版本庫中,這樣在build環境構建也能保證版本統一。

及時更新依賴

上面的版本鎖死讓你面對依賴模塊的時候更加從容,但是要記得保持定期更新依賴,從而獲得修復bug和性能優化功能完善的更新。可以每周利用 npm outdated 或 ncu 工具包

選擇合適的數據庫

大部分新的noder,在選擇數據庫,喜歡選擇Mongodb。它的確很不錯,但是 Mongodb 不是唯一的選擇、
你應該根據你的應用場景來選擇:

  • 你的數據是否結構化的
  • 你的數據操作是否要支持事務
  • 你數據是否需要持久化

從而選擇不同的數據庫:如 PostgreSQL, Redis, LevelDB 等等

監控你的應用程序

你要對你的線上應用的運行狀況了如指掌(CPU,Memory,日志等),對一些突發情況需要及時獲得通知。
很多開源項目和SaaS產品都提供完善強大的監控服務,如Zabbix, Collectd, ElasticSearch 和 Logstash. 甚至結合Cabot給微信公眾號發消息提醒等等

使用構建系統

現在的JavaScript的工具鏈有大量的選擇: Grunt, Gulp, Webpack等。譬如在團隊裡,我們選擇 Webpack 來輔助前端開發,gulp用來處理大量其他的自動化任務(你的shell腳本也可以通過gulp-shell集成進來)。當然我們也推薦使用 vanilla build (尤其你可以結合 npm lifecycle hooks 完成很多事)

NPM 生命周期鉤子

提供了很好的鉤子來使得一些task實現的很優雅,我們的腳手架大量使用了這樣的技巧

"postinstall": "bower install && grunt build",

"postinstall": "if $BUILD_ASSETS; then npm run build-assets; fi",
"build-assets": "bower install && grunt build"

# 如果腳本變復雜可以單獨文件:
"postinstall": "scripts/postinstall.sh” (sh 腳本中會自動可以訪問到 ./node_modules/.bin 中的命令,因為該路徑被加入到 $PATH)

管好垃圾回收

v8默認使用 lazy 和 貪婪的 GC. 有時候等到1.5GB 自由才去回收未被使用的內存 (所以有時候內存漲不是因為洩露還是node’s usual lazy behavior)

所以你不想自己的node應用經常把服務器的內存占滿(或者你不得不調整,因為你的機器可用內存沒那麼多),試著使用下面的命令/proc 文件來啟動 node 服務(推薦寫在 .pm2config 中,正如腳手架推薦的)

web: node --optimize_for_size --max_old_space_size=920 --gc_interval=100 server.js

使用長期支持的 Node.js 版本

如果你需要在不同項目中工作,並且不同項目用的node版本還不一樣,可以使用 node version manager(nvm)

使用語義化的版本號

通過三段版本數來確保把兼容性聲明好。 major.minor.patch 這樣的格式,不同級別的升級對API更新的要求也是不一樣的。可以通過semantic-release 來讓版本升級更加自動化

持續學習和跟上潮流

JavaScript 和 Node.js 社區異常活躍,的確是件好事。每周都有新的工具新的理念的加入,讓我們始終保持熱情和技術的提升(警惕自己變成跟風狗,要取色和了解每個新東西背後的不變的本質),不要待在自己的蜜罐中,要動手做試驗和學習。以下資料:

  • Node.js Weekly Newsletter
  • Microservice Weekly Newsletter
  • Changelog Weekly - for Open-Source news

下面關於Node.js的內容你可能也喜歡

在 Ubuntu 14.04/15.04 上安裝配置 Node.js v4.0.0 http://www.linuxidc.com/Linux/2015-10/123951.htm

如何在CentOS 7安裝Node.js http://www.linuxidc.com/Linux/2015-02/113554.htm

Ubuntu 14.04下搭建Node.js開發環境 http://www.linuxidc.com/Linux/2014-12/110983.htm

Ubunru 12.04 下Node.js開發環境的安裝配置 http://www.linuxidc.com/Linux/2014-05/101418.htm

Node.Js入門[PDF+相關代碼] http://www.linuxidc.com/Linux/2013-06/85462.htm

Node.js開發指南 高清PDF中文版 +源碼 http://www.linuxidc.com/Linux/2014-09/106494.htm

Node.js入門開發指南中文版 http://www.linuxidc.com/Linux/2012-11/73363.htm

Ubuntu 編譯安裝Node.js http://www.linuxidc.com/Linux/2013-10/91321.htm

Node.js 的詳細介紹:請點這裡
Node.js 的下載地址:請點這裡

Copyright © Linux教程網 All Rights Reserved