【個人的】 React ディレクトリ構成 のベストプラクティス


## Moduleとか色々

- React
- Redux-observable
- Typescript
- Jest

## 構成

```
Project名
　　L config
　　　　L .env.dev
　　　　L .env.prod
　　　　L .env.test
　　L node_modules（インストールされたモジュール群）
　　　　L ...
　　　　L ...
　　　　L ...
　　L public（共通で使用するイメージや、設定ファイルなど）
　　　　L images（イメージファイルは拡張子每で分けておく）
　　　　　　L jpg
　　　　　　　　L logo.jpg
　　　　　　L png
　　　　　　　　L logo.png
　　　　　　L svg
　　　　　　　　L logo.svg
　　　　L favicon.ico
　　　　L index.html
　　　　L manifest.json
　　L src(ソースファイル格納先）
　　　　L __test__（テストファイル各要素每で分ける）
　　　　　　L components
　　　　　　L pages
　　　　　　L reducers
　　　　L _assets（イメージファイルやフォントファイル）
　　　　　　L images（イメージファイル）
　　　　　　　　L jpg
　　　　　　　　　　L front-1.jpg
　　　　　　　　L png
　　　　　　　　　　L front-1.png
　　　　　　　　L svg
　　　　　　　　　　L icon-log.svg
　　　　　　L data（データファイル）
　　　　　　　　L posts.csv
　　　　L _constants（定数ファイル）
　　　　　　L path.tsx（URIの定数）
　　　　　　L common.tsx（色や、基本の高さなどの定数）
　　　　L _components（共通コンポーネント）
　　　　　　L Header.tsx
　　　　　　L Footer.tsx
　　　　　　L SimpleLink.tsx
　　　　L pages（pagesのルートにcomponentsは作らない）
　　　　　　L home（ページ単位でディレクトリを作成）
　　　　　　L signin
　　　　　　L signup
　　　　　　　　L _components（ページ内だけで使うコンポーネント）
　　　　　　　　L index.component.tsx
　　　　　　　　L index.tsx（container/connectorに値するもの）
　　　　L services（APIなど）
　　　　　　L api
　　　　　　　　L signin.tsx
　　　　　　L calc
　　　　　　　　L add.tsx
　　　　L stores（redux関連）
　　　　　　L user（格納するstate単位）
　　　　　　L posts
　　　　　　　　L services
　　　　　　　　　　L api.tsx
　　　　　　　　　　L sort.tsx
　　　　　　　　L action.tsx
　　　　　　　　L epic.tsx
　　　　　　　　L reducer.tsx
　　　　　　　　L interface.tsx
　　　　　　L actions.tsx
　　　　　　L epics.tsx
　　　　　　L index.tsx
　　　　　　L reducers.tsx
　　　　L App.tsx
　　　　L index.tsx
　　L package.json
　　L README.md
　　L ...
　　L ...
　　L ...
```

### envの使用について

package.json に スクリプトを記述しておき、切り替え出来るようにしておく

```json
"scripts": {
  "start": "cp ./config/.env.dev .env && react-app-rewired start",
  "start:prod": "cp ./config/.env.prod .env && react-app-rewired start",
  "start:test": "cp ./config/.env.test .env && react-app-rewired start"
}
```

### manifestの使用について

基本的に react-app create で作成されたものだが、

本番対応に合わせて、マニフェストに記述されているファイルは最低でも用意しておく

例

- favicon.ico
- logo192.png

```json
{
  "short_name": "React App",
  "name": "Create React App Sample",
  "icons": [
    {
      "src": "favicon.ico",
      "sizes": "64x64 32x32 24x24 16x16",
      "type": "image/x-icon"
    },
    {
      "src": "logo192.png",
      "type": "image/png",
      "sizes": "192x192"
    }
  ],
  "start_url": ".",
  "display": "standalone",
  "theme_color": "#000000",
  "background_color": "#ffffff"
}
```

### imagesの使用について

#### public下においている場合

```xml
<img
  src={`${process.env.PUBLIC_URL}/images/png/logo.png`}
  alt={'sample'}
/>
```

#### assets下においている場合

```react
import { ReactComponent as IconLog } from '@/assets/images/svg/icon-log.svg'

...

<IconLog />
```

もしくは

```react
import samplePng from '@/assets/images/png/sample.png'

...

<img src={samplePng} alt="sample" />
```

### __test__の使用について

テストファイルは `/src/__test__` に集約しておき、他コンポーネントやページファイルの直下には置かない

内部で

```
src
　　L __test__
　　　　L components
　　　　L pages
　　　　L reducers
```


などとして、場合分けをして、テストファイルはここで完結するようにする


### pagesの使用について

pages直下のディレクトリは ページ単位で作成し、それぞれの基本となる

component => index.component.tsx
container/connector => index.tsx

とする。そうすることで、router からの呼び出しはシンプルになる

```react
import signin from '@/pages/signin'
```

構成

```
~/pages
　　L signin
　　L signup
　　L passwordForgot
```

ページ要素の component郡は 各ページ直下に `components` ディレクトリを用意し、
ここに作成する。

```
~/pages
　　L signin
　　　　L components
　　　　　　L Header.tsx
　　　　　　L Footer.tsx
　　　　L index.component.tsx
　　　　L index.tsx
```

### servicesの使用について

APIや何らかの共通処理や重い処理をしたい場合、こちらに置いておく
APIは勿論、精密な計算が必要なロジックはしっかり分けておくと、可読性も上がるし、ミスも発見しやすい

epicで処理したいものもここに置いておく

```
~/services
　　L api
　　　　L signin.tsx
　　L calc
　　　　L add.tsx
```

### storesの使用について

主としてstate/reducer/epicの流れをまとめる。
他ベストプラクティスでは、

```
~/stores
　　L actions
　　　　L user.tsx
　　L epics
　　　　L user.tsx
　　L reducers
　　　　L user.tsx
```

のような工程も多いが、今回は、使用する state 単位でまとめたかったので、以下のように state 単位でまとめる形とした。
代わりに stores のルートに それぞれをまとめるファイルを一つ挟んでいる

```
~/stores
　　L header
　　L ui
　　L home
　　L users
　　L posts
　　　　L action.tsx
　　　　L epic.tsx
　　　　L reducer.tsx
　　L actions.tsx
　　L epics.tsx
　　L reducers.tsx
```

state は pages/header/common 単位 でまとめる
epicから呼び出すものは基本的にservice層に置いておく

### @/pages/signin みたいにファイルをインポートする

`tsconfig.paths.json` を用意して以下を記述 「@」のところを「~」にしたら `~/pages/signin` みたいにして呼び出せる

```json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  }
}
```

`tsconfig.json` に `tsconfig.paths.json` を読み込ませる

```json
{
  "extends": "./tsconfig.paths.json",
  "compilerOptions": {
    ...

  }
}
```

### _assets や _components などの最初の ハイフン の意味
ファイル群の自動整列の関係上、共通ファイル群はトップに配置されているのが開発的に望ましく、フィルターでトップに置きたいために ハイフン をつけている

![Screen_Shot_2020-11-12_at_8_40_46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/720799/34a4f3da-11a9-935d-780c-933a4b52d913.png)

## 一言

```
src
　　L components
　　L pages
```

より


```
src
　　L pages
　　　　L components
```

こっちのほうがいいかな~

みなさんも意見があればお気軽にコメントください!

twitter 👉https://twitter.com/tk_r1d3r