React のディレクトリ構造に関する個人的な方針

Reactは公式でディレクトリ構造に対する明確な方針を持っておらず、各開発者の裁量に任されている。 その結果としていくつかのパターンは見られるものの個々人、プロジェクトで異なることが多く、「これが最有力!」というものも存在していない。

私自身Reactで何か作り始めると大体ここでガッツリ迷う。さっさと先に進みたいのに大変ストレスである。 ということで自分なりのベストプラクティスを作るべく調査を開始したのだが、今の所結論にはたどり着いていない。 ネット上には様々な確からしい話が渦巻いており、あっちを立ててればこっちが立たずと言ったところだった。 とはいえせっかく調べた内容を投げ出すのもなんなので、現時点での意見を備忘録も兼ねて書きなぐる。

結論(暫定)

まず最初に私が調査の結果採用したディレクトリ構造を記載する。(src直下)

- common
  - components
    - atoms...
  - hooks
  - constants
  ...
- domains
  - FeatureA
  - ...
- layouts
- App.tsx
- index.tsx
- routes.tsx

大方針

How to Organize Your React + Redux Codebase | Pluralsight

GitHub - goldbergyoni/nodebestpractices: The Node.js best practices list (August 2020)

基本的に私は上の記事で示されている、「The Application Feature Split」「Structure your solution by components」と言った考え方を採用している。

端的に言うと「機能毎にディレクトリを分割」する方針だ。 機能ディレクトリ毎に独立した小さなソフトウェアを作成する形をとることで、コードの凝集度や結合度を適切な範囲に抑え、可読性の担保やリファクタリング時の影響範囲を抑えることを重視している。 「マイクロサービス」アーキテクチャの考え方に近いかもしれない。

懸念点

この方針をとった場合、以下のような一般的に使われている他の考え方とバッティングする。 大方針を重視しつつ、可能な範囲で取り入れていく。 (取り入れていくと言いつつネガってるだけかもしれない)

pages

pages下にルーティングと対応した各機能の入り口となるコンポーネントを作る形。 おそらくNext.jsからきているのだと思うが、React単体でこれを取り入れるメリットがいまいち分からない。 ルーティングの関心毎を分離させておくことに十分な価値があると言うことだろうか。 Next.jsを使ってみれば実感できるのだろうか。

現時点では取り入れないが、メリットを理解できる機会が訪れれば再度検討したい。(おそらく遠からずやる)

containers

Reduxのstoreをconnectするためのコンポーネント。いわゆるPresentational ComponentとContainer Componentの後者に当たるイメージ。 機能の違いを考慮せず、containerに該当するコンポーネントを1つのディレクトリにまとめるような構成は、やはりメリットが分からないのでやらない。 機能毎に分けたディレクトリの下で、"container"ディレクトリを作成するのは場合によってはあり得るかもしれない。

ただ、Presentational ComponentとContainer Componentをキッチリ分けること自体hooksの登場によって必然性が薄れてきているので、 (Presentational and Container Components | by Dan Abramov | Mediumの"Update from 2019:" 参照) 正直あまりやるメリットを感じない。

もちろん「reduxに依存したコンポーネントはなるべく減らしたい」という話は理解できる。しかしディレクトリ構造に反映するか必要があるとは思わない。

atomic design

コンポーネントを作成する粒度の目安と言う意味では非常に有用だと思うが、これをディレクトリ構造に落とし込む(atoms, molucules, ...など)のは、コードの可読性や修正時の影響範囲の問題から危険だと考えている。(規模にもよる) 加えて私がとっている大方針(The Application Feature Split)とは特に相性が悪い。

ただ共通コンポーネント用のディレクトリ(shared/component下など)では十分に活用できるように思う。 一方で私のようにMATERIAL-UI, AntDesignといったDesignSystemに頼りきりな人間は、そもそも共通コンポーネントをあまり作らないように思う(またそれを是とする)ので、 結局うまくatomic designを活用する機会はないのではないか、という印象もある。

参考サイト

一番参考にした記事

https://www.pluralsight.com/guides/how-to-organize-your-react-+-redux-codebase https://github.com/goldbergyoni/nodebestpractices#1-project-structure-practices

そこそこ

https://www.robinwieruch.de/react-folder-structure https://medium.com/@ger86/reactjs-the-folder-structure-i-feel-most-comfortable-with-694edaed0065

少し参考

https://medium.com/javascript-in-plain-english/choosing-the-best-folder-structure-for-your-react-application-cba4885b3a2 https://blog.bitsrc.io/structuring-a-react-project-a-definitive-guide-ac9a754df5eb https://dev.to/farazamiruddin/an-opinionated-guide-to-react-folder-structure-file-naming-1l7i

twitter

大岡由佳『りあクト! 第3版』Booth/Amazonで近日刊行 on Twitter: "React アプリの src/ 配下ディレクトリ構成、いろいろ試した末、最近はこんな感じに行き着いてる。 components/ common/ atoms/ containers/ domains/ mangarel/ models/ services/ utils/ constants.ts schema-org/ utils/"

参考リポジトリ

GitHub - devias-io/react-material-dashboard: React Dashboard made with Material UI’s components. Our pro template contains features like TypeScript version, authentication system with Firebase and Auth0 plus many other routesの実装真似したい

DIM/package.json at 8607a43ce09a327b8685b59b15a25ed262d2b94e · DestinyItemManager/DIM · GitHub コードの規模、綺麗さ、更新頻度(202008)どれをとっても良い

https://tech.offgrid-electric.com/domain-directory-structure-for-react-apps-why-its-worth-trying-b3855ee77a1e app ディレクトリ作るのもありか