作者:@htoooth
本文為作者原創(chuàng),轉(zhuǎn)載請(qǐng)注明出處:http://www.cnblogs.com/htoooth/p/7181864.html


目錄

思想
按業(yè)務(wù)特性而不按分層進(jìn)行規(guī)劃
邊界顯式說(shuō)明
落實(shí)
總結(jié)

express 最佳實(shí)踐 (一)

最近,一直在使用 nodejs 做項(xiàng)目,對(duì) nodejs 開(kāi)發(fā)可以說(shuō)深有體會(huì)。

先說(shuō)說(shuō) nodejs 在業(yè)務(wù)中的腳色,, 在 web同構(gòu) 方面, nodejs 的優(yōu)勢(shì)相對(duì)于其他語(yǔ)言來(lái)說(shuō),可以說(shuō)非常巨大,基本上算是只有 nodejs 能做,其他語(yǔ)言根本不能做。在傳統(tǒng) web 開(kāi)發(fā)方面,nodejs(必竟時(shí)間太短了)的相對(duì)于其他語(yǔ)言來(lái)說(shuō)的劣勢(shì),已經(jīng)不是太明顯了。

再來(lái)說(shuō)說(shuō)自己,算了算差不多做了 5 個(gè)項(xiàng)目,都是使用 express 做為項(xiàng)目的基礎(chǔ)框架,然后再上面進(jìn)行業(yè)務(wù)開(kāi)發(fā)工作,一個(gè)路由下來(lái),平均 10 個(gè)左右的中間件,執(zhí)行效率都是不錯(cuò)的,開(kāi)發(fā)效率也非常好,是時(shí)候總結(jié)一下 express 實(shí)踐經(jīng)驗(yàn),同時(shí)結(jié)合配套自己的想法,來(lái)看看理想中 express 項(xiàng)目應(yīng)該是怎樣的規(guī)劃,以及我是怎么想的。

思想

做一個(gè)項(xiàng)目的規(guī)劃,首先要為項(xiàng)目訂一個(gè)基調(diào),就是項(xiàng)目架構(gòu)是應(yīng)該怎樣設(shè)計(jì),怎樣考慮的,對(duì)業(yè)務(wù)開(kāi)發(fā)是否方便,部署是否方便等要素。

我現(xiàn)在認(rèn)為一個(gè)項(xiàng)目最重要的規(guī)劃是:核心+插件式開(kāi)發(fā)。一個(gè)項(xiàng)目一定要支持這兩點(diǎn),如果不支持這個(gè)項(xiàng)目就很難做下去,為什么我這樣說(shuō)。因?yàn)楝F(xiàn)在的任何一個(gè)項(xiàng)目都不可能是一個(gè)人開(kāi)發(fā),一定是多人分工開(kāi)發(fā),如果你的項(xiàng)目支持 核心+插件式開(kāi)發(fā),你就可以把核心的基礎(chǔ)功能如:網(wǎng)絡(luò),日志,基礎(chǔ)布局等功能,找個(gè)高級(jí)工程師來(lái)完成;業(yè)務(wù)開(kāi)發(fā),就可以分給一些初級(jí)工程師,并行完成,同時(shí)在做項(xiàng)目的時(shí)候?qū)Υa碼進(jìn)行審查,及時(shí)調(diào)整壞代碼。這樣項(xiàng)目,能保證進(jìn)度,也能保證項(xiàng)目質(zhì)量,不會(huì)大爛,同時(shí)人力也得到了充分利用。

這種思想落實(shí)到架構(gòu)上,就是從項(xiàng)目的文件組織結(jié)構(gòu)上考慮怎樣達(dá)到這樣的目標(biāo)。

我是這樣規(guī)劃文件目錄的:

按業(yè)務(wù)特性而不按分層進(jìn)行規(guī)劃

分層最典型的代表就是ruby on rails,app 目錄下,就是 controllers, models等目錄,當(dāng)然我不是說(shuō),這種規(guī)劃不好,只是到項(xiàng)目大到一定程度,你想找某個(gè) controller 下的一個(gè)方法,就會(huì)很麻煩,不知道沒(méi)有這種體驗(yàn),在幾十個(gè)文件中找某個(gè)方法是怎樣的感覺(jué),搜索也是全文搜索,不能限定到某個(gè)目錄下面。因此在這個(gè)項(xiàng)目規(guī)劃中,以業(yè)務(wù)特征為插件名,在 express 中,也就是 subExpress,如果,我有一個(gè)購(gòu)物車(chē)的業(yè)務(wù),那于購(gòu)物車(chē)相關(guān)的所有的項(xiàng)目都規(guī)在 passport 這個(gè)子應(yīng)用下了,這樣相關(guān)的業(yè)務(wù)在一起,方便查找,同時(shí)也方便理解和修改。當(dāng)然這種規(guī)劃方式也有不方便的地方,如果想跨 subApplication 調(diào)用方法,就沒(méi)有那么方便。

邊界顯式說(shuō)明

這個(gè)跟傳統(tǒng)的 controller, service , model 沒(méi)有什么區(qū)別。還是剛才的 passport 應(yīng)用,按分層進(jìn)行劃分,包括 controllers, services, models, views, index.js, router.js。需要說(shuō)明一下,在項(xiàng)目中我們一再?gòu)?qiáng)調(diào), controllers 中負(fù)責(zé)與 http 的連接工作,只做簡(jiǎn)單參數(shù)的驗(yàn)證,傳參和調(diào)起 services ,禁止把 rep, res 對(duì)像做為參數(shù)傳遞到 services 層;services 層純業(yè)務(wù),沒(méi)有與 http 相關(guān)的任何東西,需要數(shù)據(jù)請(qǐng)調(diào)用 models 中的方法;models 只于數(shù)據(jù)打交到,其它都不管。這樣做的好處是什么呢? 想想看,如果相把一個(gè)頁(yè)面的數(shù)據(jù)拿出來(lái)做接口,只需要簡(jiǎn)單幾行就搞定了,還有如果要把框架改成 koa ,你的業(yè)務(wù)都不用重寫(xiě),還有你想增加 websocket 的支持,直接在 controllers 進(jìn)行調(diào)整就行了。 models的作用更明顯,原來(lái)的項(xiàng)目是一個(gè)普通是 web 項(xiàng)目,models 是連接數(shù)據(jù)庫(kù)的,現(xiàn)在技術(shù)升級(jí)要前后端分離,不用數(shù)據(jù)庫(kù)了,改成調(diào)用后端的接口了,你就只用把 models 用接口實(shí)現(xiàn)一遍,其他不用變了。 controllers 和 models 就是你業(yè)務(wù)的邊界,service 則是你業(yè)務(wù)的核心,邊界實(shí)現(xiàn)的改變不應(yīng)該影響你業(yè)務(wù)。

落實(shí)

思想利用 express 的中間件思想,達(dá)到我的架構(gòu)意圖,如下圖所示:

seo優(yōu)化培訓(xùn),網(wǎng)絡(luò)推廣培訓(xùn),網(wǎng)絡(luò)營(yíng)銷(xiāo)培訓(xùn),SEM培訓(xùn),網(wǎng)絡(luò)優(yōu)化,在線營(yíng)銷(xiāo)培訓(xùn)

圖中,藍(lán)色的部分代表業(yè)務(wù)中間件,橙黃色代表 核心中間件。在一個(gè)網(wǎng)站項(xiàng)目中核心中間件,應(yīng)該包括 limiter 限流操作,這個(gè)中間件主要是防止爬蟲(chóng);htaccess 改寫(xiě) url,這個(gè)中間件主要用,改寫(xiě)網(wǎng)站url, 為什么要改呢?因?yàn)橐坏W(wǎng)站線上運(yùn)行時(shí),路由的規(guī)則不應(yīng)發(fā)生變化,但是有時(shí)候 seo 的時(shí)候,你需要兼容新老 url 的時(shí)候,這個(gè)中間件就會(huì)非常有用,網(wǎng)站的業(yè)務(wù)都不用變,只用在新url 到達(dá)時(shí),變成老的再進(jìn)行處理就行了;dispatch 不是一個(gè)中間件,它的思想是用來(lái)整合各個(gè)業(yè)務(wù)線的 subApplication 和主 application 的關(guān)系的;auth 鑒權(quán),有些頁(yè)面和接口需要有用戶登錄,如果沒(méi)有用戶登錄,就需要跳轉(zhuǎn)到登錄頁(yè)面,登錄完成后跳回來(lái);clientError 和 serverError 是對(duì)錯(cuò)誤進(jìn)行統(tǒng)一的處理,統(tǒng)一顯示 404 , 如果是接口的話也會(huì)統(tǒng)一 404 的返回碼。

業(yè)務(wù)端在開(kāi)發(fā)時(shí)只需要在 dispatch 的地方加入自已的模塊,然后就可以開(kāi)始寫(xiě)自己的業(yè)務(wù),不用但心自己的文件被別人改動(dòng)。

下面是項(xiàng)目的文件夾規(guī)劃:

seo優(yōu)化培訓(xùn),網(wǎng)絡(luò)推廣培訓(xùn),網(wǎng)絡(luò)營(yíng)銷(xiāo)培訓(xùn),SEM培訓(xùn),網(wǎng)絡(luò)優(yōu)化,在線營(yíng)銷(xiāo)培訓(xùn)

簡(jiǎn)單說(shuō)明下:

apps 目錄下就寫(xiě)各自的業(yè)務(wù)邏輯,用 dispatch 把 主app 與 業(yè)務(wù) 連接起來(lái),實(shí)現(xiàn)起來(lái)也挺簡(jiǎn)單的:

1
2
3
module.exports = (app) => {
  app.use('/passport', require('./apps/passport'));
}

還有 shared 的存在,是為了解決前后端模板公用的問(wèn)題。

與業(yè)務(wù)沒(méi)有關(guān)系的代碼可以,移到到 modules 中使用。

如果個(gè)業(yè)務(wù)的之間需要共享部分代碼,就放到 utils 中,這個(gè)文件夾就是用來(lái)干這種事的。

總結(jié)

這個(gè)項(xiàng)目中規(guī)劃就是,怎樣使用 express 最好,另外再加上自己的一些思考,現(xiàn)在項(xiàng)目的結(jié)構(gòu)出來(lái)了,后面會(huì)再討論一些有關(guān)中間件的處理方法。

http://www.cnblogs.com/htoooth/p/7181864.html