第二篇: express 最佳實踐(二):中間件html
最近,一直在使用 nodejs 作項目,對 nodejs 開發能夠說深有體會。node
先說說 nodejs 在業務中的腳色,, 在 web同構
方面, nodejs 的優點相對於其餘語言來講,能夠說很是巨大,基本上算是隻有 nodejs 能作,其餘語言根本不能作。在傳統 web 開發
方面,nodejs(必竟時間過短了)的相對於其餘語言來講的劣勢,已經不是太明顯了。git
再來講說本身,算了算差很少作了 5 個項目,都是使用 express 作爲項目的基礎框架,而後再上面進行業務開發工做,一個路由下來,平均 10 個左右的中間件,執行效率都是不錯的,開發效率也很是好,是時候總結一下 express 實踐經驗,同時結合配套本身的想法,來看看理想中 express 項目應該是怎樣的規劃,以及我是怎麼想的。github
作一個項目的規劃,首先要爲項目訂一個基調,就是項目架構是應該怎樣設計,怎樣考慮的,對業務開發是否方便,部署是否方便等要素。web
我如今認爲一個項目最重要的規劃是:核心+插件式開發
。一個項目必定要支持這兩點,若是不支持這個項目就很難作下去,爲何我這樣說。由於如今的任何一個項目都不多是一我的開發,必定是多人分工開發,若是你的項目支持 核心+插件式開發
,你就能夠把核心的基礎功能如:網絡,日誌,基礎佈局等功能,找個高級工程師來完成;業務開發,就能夠分給一些初級工程師,並行完成,同時在作項目的時候對代碼碼進行審查,及時調整壞代碼。這樣項目,能保證進度,也能保證項目質量,不會大爛,同時人力也獲得了充分利用。數據庫
這種思想落實到架構上,就是從項目的文件組織結構上考慮怎樣達到這樣的目標。express
我是這樣規劃文件目錄的:後端
分層最典型的表明就是ruby on rails
,app 目錄下,就是 controllers, models等目錄,固然我不是說,這種規劃很差,只是到項目大到必定程度,你想找某個 controller 下的一個方法,就會很麻煩,不知道沒有這種體驗,在幾十個文件中找某個方法是怎樣的感受,搜索也是全文搜索,不能限定到某個目錄下面。所以在這個項目規劃中,以業務特徵爲插件名,在 express 中,也就是 subExpress,若是,我有一個購物車的業務,那於購物車相關的全部的項目都規在 passport
這個子應用下了,這樣相關的業務在一塊兒,方便查找,同時也方便理解和修改。固然這種規劃方式也有不方便的地方,若是想跨 subApplication 調用方法,就沒有那麼方便。ruby
這個跟傳統的 controller, service , model 沒有什麼區別。仍是剛纔的 passport 應用,按分層進行劃分,包括 controllers, services, models, views, index.js, router.js。須要說明一下,在項目中咱們一再強調, controllers 中負責與 http 的鏈接工做,只作簡單參數的驗證,傳參和調起 services ,禁止把 rep, res 對像作爲參數傳遞到 services 層;services 層純業務,沒有與 http 相關的任何東西,須要數據請調用 models 中的方法;models 只於數據打交到,其它都無論。這樣作的好處是什麼呢? 想一想看,若是相把一個頁面的數據拿出來作接口,只須要簡單幾行就搞定了,還有若是要把框架改爲 koa ,你的業務都不用重寫,還有你想增長 websocket 的支持,直接在 controllers 進行調整就好了。 models的做用更明顯,原來的項目是一個普通是 web 項目,models 是鏈接數據庫的,如今技術升級要先後端分離,不用數據庫了,改爲調用後端的接口了,你就只用把 models 用接口實現一遍,其餘不用變了。 controllers 和 models 就是你業務的邊界,service 則是你業務的核心,邊界實現的改變不該該影響你業務。websocket
思想利用 express 的中間件思想,達到個人架構意圖,以下圖所示:
圖中,藍色的部分表明業務中間件,橙黃色表明 核心中間件。在一個網站項目中核心中間件,應該包括 limiter 限流操做,這個中間件主要是防止爬蟲;htaccess 改寫 url,這個中間件主要用,改寫網站url, 爲何要改呢?由於一但網站線上運行時,路由的規則不該發生變化,可是有時候 seo 的時候,你須要兼容新老 url 的時候,這個中間件就會很是有用,網站的業務都不用變,只用在新url 到達時,變成老的再進行處理就好了;dispatch 不是一箇中間件,它的思想是用來整合各個業務線的 subApplication 和主 application 的關係的;auth 鑑權,有些頁面和接口須要有用戶登陸,若是沒有用戶登陸,就須要跳轉到登陸頁面,登陸完成後跳回來;clientError 和 serverError 是對錯誤進行統一的處理,統一顯示 404 , 若是是接口的話也會統一 404 的返回碼。
業務端在開發時只須要在 dispatch 的地方加入自已的模塊,而後就能夠開始寫本身的業務,不用但心本身的文件被別人改動。
下面是項目的文件夾規劃:
簡單說明下:
apps 目錄下就寫各自的業務邏輯,用 dispatch 把 主app 與 業務 鏈接起來,實現起來也挺簡單的:
module.exports = (app) => { app.use('/passport', require('./apps/passport')); }
還有 shared 的存在,是爲了解決先後端模板公用的問題。
與業務沒有關係的代碼能夠,移到到 modules 中使用。
若是個業務的之間須要共享部分代碼,就放到 utils 中,這個文件夾就是用來幹這種事的。
這個項目中規劃就是,怎樣使用 express 最好,另外再加上本身的一些思考,如今項目的結構出來了,後面會再討論一些有關中間件的處理方法。
該項目的 github