如何合理佈置React/Redux的目錄結構

Git blog地址: github.com/asd0102433/…
喜歡的同窗star支持一下,長期更新javascript

項目的結構改過不少次,每次根據需求的複雜度慢慢的修改,總結下幾種結構的特色。html

按照文件類型劃分,不是很複雜的項目能夠這樣規劃。java

|—— 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個目錄下操做,以及跨文件的管理對應的文件,有點不方便。react


按照組件劃分,一個組件包含自身action,reducers,style等相關的文件,這樣在修改某些文件的時候就很是的容易。對於項目不存在很複雜的異步邏輯等能夠參考這樣的結構。git

|—— 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 boilerplategithub

|——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等。構建大型的項目結構參考這個也是一個很是棒的。redux


react boilerplate 確實能夠解決大型項目的結構問題,可是component 和佈局結構混合在一塊兒,並無分離出去,下面這種結構分離了組件,佈局模塊,更好的管理項目(文件結構同時也增長了複雜度)。mvc

|── 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 代碼app

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是一件很差的事情。

項目的結構並不是要跟上面相同,根據本身的需求和理解來構建本身的項目也是一件很是美好的事情。

相關文章
相關標籤/搜索