React系列—React+Redux工程目錄結構劃分

zhutianxiang發表於2017-07-27

按角色組織

如果你用MVC框架開發過應用,應該知道MVC框架之下,通常有這樣一種程式碼組織方式:

controllers/
  todoController.js
  filterController.js
models/
  todoModel.js
  filterModel.js
views/
  todo.js
  todoItem.js
  filter.js

ControllerModelView分別代表三種模組角色。這種組織程式碼的方式叫做“按角色組織”。

因為MVC的影響深遠,一些風格依然影響了前端人員的思維方式,在Redux應用的構建中,就有這種組織方式:

reducers/
  todoReducer.js
  filterReducer.js
actions/
  todoAction.js
  filterActions.js
components/
  todoList.js
  todoItem.js
  filter.js
containers/
  todoListContainer.js
  todoItemContainer.js
  filterContainer.js

角色如下:

  • reducers 目錄包含所有Redux的reducer;
  • actions 目錄包含所有action建構函式;
  • components 目錄包含所有的展示元件;
  • containers 目錄包含所有的容器元件。

這種按角色組織的方式看起來不錯,實際非常不利於應用的擴充套件。當你需要對一個功能進行修改時,要在多個角色目錄下切換,當功能模組多了,這種頻繁的目錄切換即浪費時間也增加了編碼厭倦感。

如果說MVC框架下,因為三個角色之間的交叉關係,也只能默默接受,那麼在Redux框架下,我們已經有機會實行嚴格模組化思想。

按功能組織

Redux應用適合於“按功能組織”,也就是把完成同一應用功能的程式碼放在一個目錄下,一個應用功能包含多個角色的程式碼。Redux中,不同的角色就是reduceractions和檢視,而應用功能對應的就是使用者介面的互動模組。

Todo應用來說,兩個基本的功能就是TodoListFilter,所以按功能組織就是這樣子:

todoList/
  actions.js
  actionTypes.js
  index.js
  reducer.js
  views/
    components.js
    containers.js
filter/
  actions.js
  actionTypes.js
  index.js
  reducer.js
  views/
    components.js
    container.js

每個功能模組對應一個目錄,分別是todoListfilter,每個目錄下包含同樣的角色檔案:

  • actionTypes.js 定義action型別;
  • actions.js 定義action建構函式;
  • reducer.js 定義這個功能模組如果響應actions.js定義的動作;
  • views 包含功能模組中所有的React元件,包括展示元件和容器元件;
  • index.js 把所有的角色匯入,統一匯出。

這種組織方式下,當你要修改某個模組時,只要關注對應的目錄即可。

按功能組織下的每個模組,都有一個index.js,明確了模組對外的介面:

import * as actions from `./actions.js`;
import reducer from `./reducer.js`;
import view from `./views/container.js`;

export { actions, reducer, view };

當filter模組依賴todoList模組時,對應的匯入程式碼:

import { actions, reducer, view as TodoList } from `../todoList`;

混合方式

大型應用中,下面這種混合方式(既採用型別劃分的優勢,又新增了功能劃分的特點)也是不錯的選擇。

src/                 所有原始碼存放的路徑
  app.js             整個應用的入口
  views/             應用中某個頁面的入口檔案,一般為路由元件
    Home.js          例如,首頁的入口就是Home.js
    Home.css         Home頁面對應的樣式
    HomeRedux.js     Home頁面中所有與Redux相關的reducer、action creator的彙總,即components/Home/下所有*Redux.js的彙總
  components/        所有應用的元件
    Home/            例如,views/中一個名為Home的view,則在components/中就有一個名為Home的子資料夾
      Table.js       Home頁面中的一個列表元件
      Table.css      列表元件對應的樣式
      TableRedux.js  列表元件的reducer、action creator及action type,整合在一個檔案中
      Modal.js
      Modal.css
      ModalRedux.js
    shared/          不歸屬於任何view的元件,如一些公共元件等
  containers/
    DevTools.js      配置DevTools
    Root.js          一般被app.js依賴,用於根據環境判斷是否需要載入DevTools
  layouts/           佈局相關的元件及樣式,如選單、側邊欄、header、footer等
  redux/             Redux store相關的配置
    reducers.js      整個應用中所有reducer的彙總
  routes/            路由相關的配置
  utils/             工具函式、常量等
  styles/            全域性公共樣式
  app.css            應用主樣式表

基本上,我們只需要關注的就是views/和components/這兩個目錄,它們也是存放絕大多數業務程式碼的地方。

在views/目錄中,存放的是每個路由的入口頁,如首頁(Home)、詳情頁(Detail)、管理後臺頁(Admin)等。而每個入口都會有三個檔案:.js是入口的元件,.css是對應元件的樣式,而*Redux.js是components/Home/目錄下所有reducer和action的聚合。

在components/Home/目錄裡,是當前路由對應的頁面(Home)需要的所有內容——components、actions、reducers、樣式等。

什麼是*Redux.js?實際上,按照Redux應用的一般目錄結構劃分方式,應該分別有reducers、action creator和constants資料夾。但是在實際應用中,我們發現這樣的劃分方式略顯繁瑣,新增一個元件需要至少新建4個檔案。同時對於業務應用來說,reducers等於Redux相關的檔案並不太可能被其他地方複用,因此放在一個檔案裡組織並管理是更好的選擇。目前在Redux社群中也存在一個類似的規範。Ducks modular redux

相關文章