Reactを使ってTODOアプリを作成する　Material UIのインポート　CSS Moduleの環境設定

# TODOアプリ
前回に引き続きReactを用いてTODOアプリを作成していこうと思います。
ただし、React初心者なので以下の手順で作成していこうと思います。

1. JavaScriptで作成（サーバー側はJSON Serverを使用しaxiosを用いてデータの取得、更新を行う）
1. JavaScript → TypeScriptに変換
1. **Material UIを使用してデザインをつける**
1. Java（Spring Boot）を用いてサーバー側を構築
1. AWS？を使用してデプロイする

今回から、`3. Material UIを使用してデザインをつける`を行なっていきます。
今回の記事は`Material UI`を適用させる前の事前準備を行います。
# 前回まで
前回はJavaScript→TypeScriptに変換を行いました。

https://qiita.com/Jackoguro/items/21d6c5b99a0791a3ce25

# Material UI / Material iconsのインポート
今回の開発で使用したMaterial UI / Material iconsをインポートします。
Material UIを用いた開発を行うための事前準備はモジュールをインポートすることで一通り完了します。

https://mui.com/material-ui/getting-started/overview/

## Material UI
npm
```console
npm install @mui/material @emotion/react @emotion/styled
```

yarn
```console
yarn add @mui/material @emotion/react @emotion/styled
```

## Material icons

npm
```console
npm install @mui/icons-material
```

yarn
```console
yarn add @mui/icons-material
```

# CSSを適用
実際にMaterial UIを用いた開発を行い感じた印象として、自分でCSSをほとんど書かずとも既存の用意されているもので大体のものは作成できる反面、すでに完成されているためアレンジがしづらい印象を受けました。なので、独自のCSSを適用できるような環境を設定してきます。

ReactにCSSを適用する方法として以下の方法があります。
1. 直接ファイルに書き込む
1. Pure CSSを適用する
1. CSS Moduleを適用する

## 1. 直接ファイルに書き込む
以下のようにして直接書き込むことができます。
この書き方だと`レイアウトに必要なコード(CSS)`と`表示に必要なコード(JSX)`コードが混在しているため、コードの可読性を下げてしまいます。なので、あまり推奨されない書き方になります。
```typescript:sample.tsx
import { Box } from "@mui/material";

// 省略

const sample = () => {
    return (
        <Box
            // sx={{...}}内にCSSのコードを記述する
            sx=
            {{
                fontSize: "14px",
                color: "white",
                textAlign: "center"
            }}
        >
            // 省略
        </Box>
    );
}
```

## 2. Pure CSSを適用する
Pure CSSとはcreate-react-appした時にデフォルトで適用されているCSSです。
HTML/CSSのスタイルと近い書き方をすることができます。

この書き方では、同じ`className`を記述してしまうと、本来CSSを適用させてくないコンポーネント側にもCSSを適用させてしまいます。つまり、予想していないレイアウトになってしまう可能性があります。
```typescript:sample1.tsx
// sample.cssをインポートする
import "./sample.css"

// sample.cssで記述したクラス名「.sampleText」を適用させる
const sample1 = () => {
    return <p className="sampleText">こんにちは</p>;
}
```

```typescript:sample2.tsx
const sample２ = () => {

    // ファイルsample2.tsxではsample.cssをインポートしていないが、
    // クラス名「.sampleText」が適用されてしまう
    return <p className="sampleText">こんにちは</p>;
}
```

```sample.css
.sampleText {
    color: red;
}
```

## 3. CSS Moduleを適用する
CSS Moduleは、CSSの適用範囲をコンポーネント単位で閉じようという考えで作られたものです。
CSS Moduleを設定するための方法は以下になります。
1. プラグインのインストール
1. global.d.tsの作成
1. tsconfig.jsonの編集
1. CSS Moduleのインポート

### 1. プラグインのインストール
npm
```console.log
npm install css-module-types
```

yarn
```console.log
yarn add css-module-types
```

### 2. global.d.tsの作成
srcフォルダと同じ階層に`global.d.ts`を作成し、以下の内容を記述します。
![スクリーンショット 2023-05-07 17.41.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884987/0404b641-dfba-0f86-0017-861b46103d7d.png)

```typescript:global.d.ts
// sassを利用する場合は`*.css`→`*.sass`に変更する
declare module '*.css' {
    const exports: {
        [exportName: string]: string
    };
    export = exports
}
```

### 3. tsconfig.jsonの編集
ファイル`tsconfig.json` に以下の2行を追加します。
```json:tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "plugins": [{"name": "css-module-types"}], ← 追加
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "include": [
    "src",
    "global.d.ts"　← 追加
  ]
}
```

### 4. CSS Moduleのインポート
例として以下のようなツリー構成で考えます。
cssの名前は`*.module.css`とします。`*`には任意の名前を記述する
```console
src
 ┣component
 ┃　　　　　　　　┗sample.tsx
 ┗css
   ┗sample.module.css
```

```typescript:sample.tsx
// 任意のモジュール名（今回はSample）をつけて、cssファイルをインポートする
// cssファイルまでの相対パスを記述する
import Sample from "../css/sample.module.css"

const sample = () => {
    return （
        // {モジュール名.クラス名}とすることでCSSを適用できる
        <p className={Sample.text1}>こんにちは<p>

        // 複数のクラスを適用させたい場合
        // {`${モジュール名.クラス名} ${モジュール名.クラス名} ...`}とする
        <p className={'${Sample.text2} ${Sample.text3}'}>こんばんわ<p>
    ）;
}
```

```css:sample.module.css
text1 {
    color: red;
}

text2 {
    font-size: 14px;
}

text3 {
    text-align: center;
}
```

参考文献

https://cod-sushi.com/cra-typescript-cssmodules/

# 最後に
以上でCSS Moduleの環境設置は完了しました。
次回は実際にMaterial UIを用いてレイアウトの作成を行っていきます。