背景
最近看了 antd pro 發(fā)現(xiàn)其項(xiàng)目的目錄結(jié)構(gòu)組織的不錯(cuò)。然后再按照自己的項(xiàng)目經(jīng)驗(yàn),對(duì)其項(xiàng)目的組織進(jìn)行修改,現(xiàn)在總結(jié)下自己的想法。
正題
我們看下 antd pro 自己生成的目錄結(jié)構(gòu)
├── mock # 本地模擬數(shù)據(jù)
├── public
│ └── favicon.ico # Favicon
├── src
│ ├── assets # 本地靜態(tài)資源
│ ├── common # 應(yīng)用公用配置,如導(dǎo)航信息
│ ├── components # 業(yè)務(wù)通用組件
│ ├── e2e # 集成測(cè)試用例
│ ├── layouts # 通用布局
│ ├── models # dva model
│ ├── routes # 業(yè)務(wù)頁面入口和常用模板
│ ├── services # 后臺(tái)接口服務(wù)
│ ├── utils # 工具庫(kù)
│ ├── g2.js # 可視化圖形配置
│ ├── theme.js # 主題配置
│ ├── index.ejs # HTML 入口模板
│ ├── index.js # 應(yīng)用入口
│ ├── index.less # 全局樣式
│ └── router.js # 路由入口
├── tests # 測(cè)試工具
├── README.md
└── package.json
區(qū)分通用組件和業(yè)務(wù)組件
由于 antd pro 本身引用了 antd 的組件庫(kù),所以不存在自己寫通用組件的步驟。但是有的時(shí)候我們自己項(xiàng)目會(huì)有自己寫通用組件的需要。組件除了有通用組件,還會(huì)有業(yè)務(wù)組件。通用組件是粒度比較細(xì)且和業(yè)務(wù)無關(guān)的組件,譬如 Dropdown。而業(yè)務(wù)組件可能是你這個(gè)項(xiàng)目特有的,譬如工具欄,或者某種特殊的彈框。業(yè)務(wù)組件大多數(shù)情況是由(但不僅僅由)通用組件組成。業(yè)務(wù)組件是粒度比較粗的組件。所以這個(gè)時(shí)候我一般會(huì)把通用組件放在 components 目錄下,而新建一個(gè) widgets 目錄放業(yè)務(wù)組件,這樣分的比較清楚。不過通用組件和業(yè)務(wù)組件的劃分邊界并不是每次都能分的很清楚,有時(shí)是會(huì)相互轉(zhuǎn)換的,如果實(shí)在覺得很難區(qū)分,那可以都放在 components 下。
領(lǐng)域?qū)ο?/h3>
src/models 目錄放的是 dva model,如果你用 redux,那么這里大致可能對(duì)應(yīng)的是 state 的概念,如果用 mobx 這里隱約對(duì)應(yīng)的是 store 的概念。在我看來這些都不是 model,只能叫做狀態(tài)(state)相關(guān)。我個(gè)人理解的 model 應(yīng)該指的是領(lǐng)域?qū)ο笠簿褪穷I(lǐng)域驅(qū)動(dòng)設(shè)計(jì)(Domain-Driven Design)中的 domain object,類似于 java bean 的概念。所以我會(huì)把放在 models 下面的東西用一個(gè)新的目錄存放,通常叫 stores,而 models 下面會(huì)放領(lǐng)域?qū)ο螅╠omain object)。拿 todo list 為例,我會(huì)抽象出一個(gè) TodoItem 的領(lǐng)域?qū)ο螅涠x:
class TodoItem {
id = -1;
text = '';
done = false;
constructor( rawData ) {
if ( rawData ) {
Object.assign( this, rawData );
}
}
}
export default TodoItem;
枚舉
這個(gè)簡(jiǎn)單,通常項(xiàng)目都不會(huì)少了枚舉值,這個(gè)時(shí)候我會(huì)單獨(dú)新建一個(gè) enums 的目錄放項(xiàng)目所用到的所有枚舉對(duì)象。當(dāng)然,如果很少的話并入 common 目錄也未嘗不可。 這個(gè)時(shí)候 src 目錄基本上會(huì)變成這樣:
├── mock # 本地模擬數(shù)據(jù)
├── public
│ └── favicon.ico # Favicon
├── src
│ ├── assets # 本地靜態(tài)資源
│ ├── common # 應(yīng)用公用配置,如導(dǎo)航信息
│ ├── enums # 枚舉
│ ├── components # 通用組件
│ ├── widgets # 業(yè)務(wù)組件
│ ├── e2e # 集成測(cè)試用例
│ ├── layouts # 通用布局
│ ├── stores # 狀態(tài)相關(guān)對(duì)象(dva model)
│ ├── models # domain object
│ ├── routes # 業(yè)務(wù)頁面入口和常用模板
│ ├── services # 后臺(tái)接口服務(wù)
│ ├── utils # 工具庫(kù)
│ ├── g2.js # 可視化圖形配置
│ ├── theme.js # 主題配置
│ ├── index.ejs # HTML 入口模板
│ ├── index.js # 應(yīng)用入口
│ ├── index.less # 全局樣式
│ └── router.js # 路由入口
├── tests # 測(cè)試工具
├── README.md
└── package.json
精簡(jiǎn)
看上目錄很多,這里我精簡(jiǎn)下,如果你的項(xiàng)目沒有復(fù)雜的布局,沒有可視化圖形配置,沒有復(fù)雜的路由且用了 react-router4,最后沒有可配置主題那么基本的目錄結(jié)構(gòu)可以精簡(jiǎn)為:
├── mock # 本地模擬數(shù)據(jù)
├── public
│ └── favicon.ico # Favicon
├── src
│ ├── assets # 本地靜態(tài)資源
│ ├── common # 應(yīng)用公用配置,如導(dǎo)航信息
│ ├── enums # 枚舉
│ ├── components # 通用組件
│ ├── widgets # 業(yè)務(wù)組件
│ ├── stores # 狀態(tài)相關(guān)對(duì)象(dva model)
│ ├── models # domain object
│ ├── routes # 業(yè)務(wù)頁面入口和常用模板
│ ├── services # 后臺(tái)接口服務(wù)
│ ├── utils # 工具庫(kù)
│ └── index.js # 應(yīng)用入口
├── tests # 測(cè)試工具
├── README.md
└── package.json
優(yōu)化
如果項(xiàng)目前期設(shè)計(jì)做的好,抽象建模工作做的到位,其實(shí)你會(huì)發(fā)現(xiàn),項(xiàng)目目錄大致還可以分為兩類:UI 相關(guān)和 UI 無關(guān)的。這個(gè)時(shí)候我會(huì)把 UI 相關(guān)的放到一個(gè) app 的目錄下,整個(gè)項(xiàng)目就會(huì)分成 MV(model,view) 的層次:
├── mock # 本地模擬數(shù)據(jù)
├── public
│ └── favicon.ico # Favicon
├── src
│ ├── app
│ │ ├── assets # 本地靜態(tài)資源
│ │ ├── components # 通用組件
│ │ ├── widgets # 業(yè)務(wù)組件
│ │ ├── stores # 狀態(tài)相關(guān)對(duì)象(dva model)
│ │ ├── routes # 業(yè)務(wù)頁面入口和常用模板
│ │ └── index.js
│ ├── common # 應(yīng)用公用配置,如導(dǎo)航信息
│ ├── enums # 枚舉
│ ├── models # domain object
│ ├── services # 后臺(tái)接口服務(wù)
│ ├── utils # 工具庫(kù)
│ └── index.js # 應(yīng)用入口
├── tests # 測(cè)試工具
├── README.md
└── package.json
這么做的用意是當(dāng)你的項(xiàng)目 UI 框架重構(gòu)的時(shí)候可以只動(dòng) app 目錄。從 redux 變到 mobx,也可以從 react 變成 angular。當(dāng)然這層抽象不是必須的,只是我個(gè)人偏好,如果要重構(gòu)通常也會(huì)整個(gè)項(xiàng)目重構(gòu)。
總結(jié)
以上就是我根據(jù) antd pro 修改的,我認(rèn)為比較通用的項(xiàng)目目錄結(jié)構(gòu)(這里沒有提到測(cè)試相關(guān))。