iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 2
0

兩種主流做法[1]

目前 React 相關的專案大多採用兩種目錄結構。

第一種:Feature-Based

user/
  User.js
  userActions.js
  userReducer.js
admin/
  Admin.js
  adminActions.js
  adminReducer.js
someProduct/
  SomeProduct.js
  someProductActions.js
  someProductReducer.js

第二種:Nature-Based

components/
  User.js
  Admin.js
  SomeProduct.js
actions/
  userActions.js
  adminActions.js
  someProductActions.js
reducers/
  index.js
  userReducer.js
  adminReducer.js
  someProductReducer.js  

各位應該可以很直覺的看出兩者差異。

Boilerplate 適用 Nature-Based

Feature-Based 比較符合模組化的精神,乍看之下似乎優於 Nature-Based 的作法,但現實中的專案不可能所有檔案都能完美按照 Feature 去歸類,因此這類的檔案在 Feature-Based 的結構下只能按照不同開發者的主觀來擺放,這主觀的擺法因人而異沒有標準,很容易破壞整體目錄結構。

Nature-Based 的結構就相對直覺,對一個剛加入專案的新人而言,甚至不用教學就能自己推測新增的檔案要擺在哪邊,我認為這樣的結構對於團隊是有利的,所以決定採用它。

考量 Isomorphic

我們使用的技術包含了 Nodejs 與 Reactjs,兩端的語法都是 Javascript,因此可以實現一個神奇的東西:Isomorphic。這個術語在 Modern Web 的領域指的是 Server-side 與 Client-side 共享同樣的程式碼片段(這邊我只先用一句話簡介,後面章節會有詳細的說明),例如表單的驗證,前後端都是一樣的檢驗邏輯,理論上只需要有一份共用的 Isomorphic Code,而不必前端寫一次,後端又寫一次。

為了避免開發時的混淆,我讓 Isomorphic 的程式碼獨立存放於 common 資料夾,而 Server-only 和 Client-only 的程式碼分別放在 serverclient 資料夾,每個資料夾內有各自的 Nature-Based 檔案結構。

client/
  components/
  actions/
  reducers/
common/
  components/
  actions/
  reducers/
  utils/
server/
  models/
  components/
  actions/
  reducers/
  utils/

考量產品生命週期

從開發、測試到上線,每個階段都可能需要產生獨立的整份程式碼,所以我將專案最頂層的目錄分為 srcbuild

build/
src/
  client/
  common/
  server/

完整目錄及檔案結構

實際上的專案還會加入許多的設定檔和相依模組,Code 也不會只有上面少少幾份,所以完整結構其實是長這樣的:

.git/
.deploy/           <-- 準備部署的檔案(設定檔、可執行檔、...)
node_modules/
configs/           <-- 專案設定
  env/             <-- 環境相關設定
  project/         <-- Web App 相關設定
build/             <-- 建置出來的可執行 Web
specs/             <-- Mocha 測試腳本
src/
  client/          <-- 只有 Client 端會使用的檔案
    index.js       <-- React App 的進入點
  common/          <-- 前後端共用的 檔案
    actions/       <-- 前後端共用的 Actions
    api/           <-- 前後端共用的 API
    components/    <-- 前後端共用的 元件
    constants/     <-- 前後端共用的 常數
    i18n/          <-- 前後端共用的 i18n 資料
    reducers/      <-- 前後端共用的 Reducers
    routes/        <-- 前後端共用的 元件路由規則
    utils/         <-- 前後端共用的 公用模組
  server/          <-- 只有 Server 端會使用的檔案
    api/           <-- 只有 Server 端會使用的 API
    components/    <-- 只有 Server 端會使用的 元件
    constants/     <-- 只有 Server 端會使用的 常數
    controllers    <-- 只有 Server 端會使用的 Controllers
    decorators/    <-- 只有 Server 端會使用的 Decorators
    middlewares/   <-- 只有 Server 端會使用的 Middlewares
    models/        <-- 只有 Server 端會使用的 Models
    routes/        <-- 只有 Server 端會使用的 路由規則
    utils/         <-- 只有 Server 端會使用的 公用模組
    index.js       <-- 注入開發環境所需的模組(如:babel-register)
    server.js      <-- Server 進入點
    app.js         <-- Express App 進入點
  public/          <-- 靜態檔案
.editorconfig
.eslintrc.json     <-- Eslint 設定檔
.gitignore
.travis.yml        <-- Travis 設定檔
gulpfile.js        <-- Gulp 腳本
LICENSE
package.json
README.md

這是 Boilerplate 的全貌,所以有些後面章節才會提到的東西目前還無法解釋清楚,請等候面章節的講解吧!另外沒解釋的部分可能是與我們的主題無關,或是太瑣碎不值得解釋,如有不懂處就請問問 Google 大神吧!

參考資料

  1. A Better File Structure For React/Redux Applications

上一篇
Day 01 - Introduction
下一篇
Day 03 - Linting
系列文
30 天打造 MERN Stack Boilerplate30

尚未有邦友留言

立即登入留言