Express＆React(vite)を使用したWebアプリ作成用の環境構築その２

## 続き
この記事の続きにを記載する
https://qiita.com/hidarikiki_toybox/items/ec7ca7368869b53c44c4

## Reactの環境構築
### Reactのプロジェクト作成
CreateReactAppは使用しない。
理由は下記の記事を参照してください。
https://zenn.dev/nekoya/articles/dd0f0e8a2fa35f

今回はVitaを使用してReactのプロジェクトを作る。
（viteの使用方法がわからないため、異なる記事にまとめる予定）
ひとまずは下記サイトを参考にして記載Viteの設定を行った。
https://zenn.dev/reasemi/articles/6869cebde469aa

cmdでbackendフォルダがある階層に移動する。

```
npm create vite@latest
```
コマンドの実行後の下記の設定する
```
Project name: ... frontend
Select a framework: » React
Select a variant: » TypeScript
```
作成したフォルダに移動する
```
npm install
```
開発環境のビルドする場合は下記
```
npm run dev
```
本番環境のビルドは下記
```
npm run build
```

### パスエイリアスの設定
tsconfig.app.jsonを下記のように修正する
```
{
  "compilerOptions": {
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
    "target": "ES2020",
    "useDefineForClassFields": true,
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "module": "ESNext",
    "skipLibCheck": true,

    /* Bundler mode */
    "moduleResolution": "Bundler",
    "allowImportingTsExtensions": true,
    "isolatedModules": true,
    "moduleDetection": "force",
    "noEmit": true,
    "jsx": "react-jsx",

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true,
    "noUncheckedSideEffectImports": true,

    /* ここから */
    /* path alias */
    "baseUrl": "./",
    "paths": {
      "@/*": ["src/*"]
    },
　　/* ここまでを追加 */
  
  },
  "include": ["src"]
}
```

vite.config.tsにも設定を反映させるために下記を実行する
```
npm i -D vite-tsconfig-paths
```
vite.config.tsに下記を追加する
```
import tsconfigPaths from "vite-tsconfig-paths";

plugins: [react(), tsconfigPaths()], /*tsconfigPathsを追加する*/
```

### テスト環境を準備する
cmdで実施する
```
npm install -D vitest happy-dom @vitest/coverage-v8 @testing-library/react @testing-library/user-event @testing-library/jest-dom
```
package.jsonのscriptsに下記を追加する
```
"test": "vitest watch",
"coverage": "vitest run --converage"
```
tsconfigと同じ階層にvitest-setup.tsを作成する
```
import "@testing-library/jest-dom/vitest"
```
vite.config.tsファイルをに追記して下記のようにする
```
/// <reference types="vitest" />
import path from 'path'
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tsconfigPaths from "vite-tsconfig-paths";

// https://vite.dev/config/
export default defineConfig({
  plugins: [react(), tsconfigPaths()],
  test: {
    environment: "happy-dom",
    setupFiles: ["./vitest-setup.ts"],
  }
})
```
tsconfig.app.jsonを下記のように修正する
```
{
  "compilerOptions": {
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
    "target": "ES2020",
    "useDefineForClassFields": true,
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "module": "ESNext",
    "skipLibCheck": true,

    /* Bundler mode */
    "moduleResolution": "Bundler",
    "allowImportingTsExtensions": true,
    "isolatedModules": true,
    "moduleDetection": "force",
    "noEmit": true,
    "jsx": "react-jsx",

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true,
    "noUncheckedSideEffectImports": true,

    /* path alias */
    "baseUrl": "./",
    "paths": {
      "@/*": ["src/*"]
    },

    /* vitest */
    "types": ["vitest/globals"] // vitestを追加する
  },
  "include": ["src", "vitest-setup.ts"] //vitest-setup.tsを追加する
}

```
srcフォルダ配下にcomponentsフォルダを作成し、TextInput.tsxとTextInput.test.tsxを作成する
```
/* TextInput.tsx */
import { useState } from "react";

const TextInput = () => {
  const [text, setText] = useState("");

  return (
    <div>
      <input
        type="text"
        value={text}
        onChange={(e) => setText(e.target.value)}
        placeholder="Enter some text"
        aria-label="Text Input"
      />
      <p>Entered Text: {text}</p>
    </div>
  );
};

export default TextInput;
```
```
/* TextInput.test.tsx */
import userEvent from "@testing-library/user-event";
import { render, screen } from "@testing-library/react";
import TextInput from "./TextInput";

test("TextInput Component Test", async () => {
  const user = userEvent.setup();
  render(<TextInput />);

  const inputElement = screen.getByLabelText("Text Input");
  expect(screen.getByText("Entered Text:")).toBeInTheDocument();

  await user.type(inputElement, "Hello World");
  expect(screen.getByText("Entered Text: Hello World")).toBeInTheDocument();
});
```
cmd上でfrontendフォルダへ移動する
下記コマンドを実行する
```
vitest watch
```

次はeslintの設定を行う