Git blog地址: github.com/asd0102433/…
喜歡的同學star支援一下,長期更新
專案的結構改過很多次,每次根據需求的複雜度慢慢的修改,總結下幾種結構的特點。
按照檔案型別劃分,不是很複雜的專案可以這樣規劃。
|—— actions
|—— CommandActions.jsx
└── newAction.jsx <- here
|—— components
|—— Command.jsx
└── newComponent.jsx <- here
|—— containers
|—— Command.jsx
└── newContainers.jsx <- here
└── reducers
|—— command.jsx
└── newReducers.jsx <- here複製程式碼
上面這種是官方demo redux.js.org/docs/advanc…
結構,actions,reducers,containers中放著每個模組的對應的結構檔案,看過去很清晰,但是有一個麻煩的地方,就是當你新增一個元件的時候你就需要在3個目錄下操作,以及跨檔案的管理對應的檔案,有點不方便。
按照元件劃分,一個元件包含自身action,reducers,style等相關的檔案,這樣在修改某些檔案的時候就非常的容易。對於專案不存在很複雜的非同步邏輯等可以參考這樣的結構。
|—— app
|—— App.jsx
|—— reducers.jsx
|—— routes.jsx
|—— home
|—— index.jsx
|—— Home.jsx
|—— HomeActions.jsx
└── HomeReducer.jsx
|—— product
|—— index.jsx
|—— ProductList.jsx
|—— ProductActions.jsx
└── ProductReducer.jsx複製程式碼
如果專案十分的巨大,大量的模組用以上的2個方案不可行,首先複用模組和特定場景下的模組需要分開進行處理,頁面的佈局view必須整理出來,可以參考react boilerplate。
|——app
|—— component # 這裡放的都是公共部分的元件
|—— Header # 使用 styled-components 來定義基礎元件
└── Fotter
|—— containers # 頁面容器
|—— HomePage
|—— ...
|—— index.js # 組織頁面的結構, 私有模組和公共模組構成
|—— reducer.js # Home下的reducer邏輯
|—— component # 私有模組
|—— sagas.js # Home下的非同步資料
|—— action.js
|—— ...
└── reducers.js # reducer複製程式碼
可以說這套專案結構很適合大型專案的組織,component下面包括了大量的通用元件,不管是專案的平臺移植,模組複用都很好管理。containers下如HomePage/index.js有複用的模組以及頁面場景下特殊的模組構成,同時index.js還負責模組跟redux store資料的連結,對應的每個場景都擁有自身saga,reducer等。構建大型的專案結構參考這個也是一個非常棒的。
react boilerplate 確實可以解決大型專案的結構問題,但是component 和佈局結構混合在一起,並沒有分離出去,下面這種結構分離了元件,佈局模組,更好的管理專案(檔案結構同時也增加了複雜度)。
|── src/
| |── views
| |—— Home.js # Home Page 頁面
| |—— HomeRedux.js # Home Redux 集合
| └── Detail.js # Detail Page 頁面
|—— redux
| └── reducers.js # 統一了views下的所有reducer
|—— layouts # layouts 負責整個app 的佈局結構
| |—— Frame.js
| |—— Nav.js
|—— components
| |—— Common # 通用元件
| |—— Home # Home Page下用到的元件
| | |—— Preview.js
| | └── PreviewRedux.js # Preview元件用到的reducer, 以及action複製程式碼
layouts
程式碼
return (
<div className="frame">
<div className="header">
<Nav />
</div>
<div className="container">
// View下面的Page 都會在此
{ this.props.children }
</div>
</div>
);複製程式碼
有了layout頁面的佈局細分就更加直觀,明晰了。在管理reducer的時候會相對的麻煩,views/ 下的主入口頁面不但負責頁面的結構,還需要整合 components/Home/ 檔案下所有的模組的reducer,需要跨檔案的處理。Home下Preview元件的reducer、action合併在一起,方便了修改同時控制自身的reducer業務邏輯(對於細分到元件的reducer,action本身邏輯也不會很龐大)。
比如 listReducer -> List ,確實很適合大型團隊的分工合作。
接下來我們來看看react-starter-kit,
github.com/bodyno/reac…
github.com/bodyno/reac… 這個專案的結構使用的是 fractal(不規則碎片形:適合大型專案)*,方法的分組主要是依照特性而不是檔案型別。注意,這個目錄結構只是一個指引,並不一定要按這個來。這種結構諧在讓程式更容易擴充套件
├── src # 程式原始檔
│ ├── main.js # 程式啟動和渲染
│ ├── components # 全域性可複用的表現元件(Presentational Components)
│ ├── containers # 全域性可複用的容器元件
│ ├── layouts # 主頁結構
│ ├── store # Redux指定塊
│ │ ├── createStore.js # 建立和使用redux store
│ │ └── reducers.js # Reducer註冊和注入
│ └── routes # 主路由和非同步分割點
│ ├── index.js # 用store啟動主程式路由
│ ├── Root.js # 為上下文providers包住元件
│ └── Home # 不規則路由
│ ├── index.js # 路由定義和程式碼非同步分割
│ ├── assets # 元件引入的靜態資源
│ ├── components # 直觀React元件
│ ├── container # 連線actions和store
│ ├── modules # reducers/constants/actions的集合
│ └── routes ** # 不規則子路由(** 可選擇的)複製程式碼
routes 作為主入口,並且把所有路由對應的元件,assets, modules全部都集中在了一起,更像mvc的命名組織。reducer、action整合為modules, components作為view,container連線actions和store。
export const createRoutes = (store) => ({
path: '/',
component: CoreLayout,
indexRoute: Home,
childRoutes: [
CounterRoute(store),
ZenRoute(store),
ElapseRoute(store),
RouteRoute(store),
PageNotFound(),
Redirect
]
})複製程式碼
一個Counter模組包含如下:
Counter/
components/ # 頁面的元件
containers/ # view 和 modules 資料對接
modules/ # 包含對應的 reducer, action
index.js # 頁面入口,定義path複製程式碼
index.js 自動的注入reducer 到store,這樣在頂層的store就無需要手動去整合每個模組自身的reducer。程式碼如下:
// 匯入對應的redicer
const reducer = require('./modules/counter').default
/* Add the reducer to the store on key 'counter' */
injectReducer(store, { key: 'counter', reducer })複製程式碼
看完這套方案真的非常酷,個人覺得多人開發專案迭代產品更新,手動的修改整合頂層reducer是一件不好的事情。
專案的結構並非要跟上面相同,根據自己的需求和理解來構建自己的專案也是一件非常美好的事情。