create-react-app も npm create も使わずに vite + React + TypeScript環境を作ってみる

## 開発環境
nodeのインストールは割愛

|項目|バージョン|備考|
|-|-|-|
|OS|Ubuntu 20.04.6 LTS|windowsのwls2上で動かしてます|
|node|18.18.0||
|vscode|*|なんでも|

## create-react-appを使いたくない理由
- 使わないライブラリを入れたくない
    - babelとかもう使わない
    - ミニマムなコードを目指す
- windowsだとセットアップが遅い
    - インストールも時間かかる
    - webpachも使いたくない
        - vite使いたい
- 依存関係がしゃらくさい
    - 調査するたびストレスホッハ（ただの面倒くさがり）
    - 自分で把握したいよね


## とりあえずやってみる

#### 空のプロジェクト作る
```sh
mkdir react-typescript-base-project
```

#### プロジェクト初期化
`yarn`派の方は適宜書き換えてください
```sh
npm init
```

とりあえずなので全部空でエンターキー連打でOKです


#### Reactインストール
今回は18.2を使いたい
```sh
npm i react@18.2 react-dom@18.2
```

#### TypeScriptインストール
特にこだわらないので最新を入れておく
```sh
npm i --save-dev typescript @types/node @types/react @types/react-dom
```

#### package.json 見てみる

```json:package.json
{
  "name": "react-typescript-base-project",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "react": "18.2",
    "react-dom": "18.2"
  },
  "devDependencies": {
    "@types/node": "^20.8.2",
    "@types/react": "^18.2.25",
    "@types/react-dom": "^18.2.10",
    "typescript": "^5.2.2"
  }
}
```

いいかんじ

#### tsconfig.json 作成
お好みで設定変えてください
```json: tsconfig.json
{
  "compilerOptions": {
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "noImplicitAny": false,
    "typeRoots": ["types", "node_modules/@types"],
    "noFallthroughCasesInSwitch": true,
    "strictPropertyInitialization": false,
    "target": "es5"
  },
  "include": ["src"]
}
```

## フォーマッター：eslint, prettier 導入
```
npm i --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-config-prettier prettier
```

#### eslintの設定ファイル作る

```sh
touch .eslintrc.json
```

お好みで設定を変えてください

```json:.eslintrc.json
{
  "env": {
    "browser": true,
    "es2021": true,
    "node": true
  },
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:@typescript-eslint/recommended"
  ],
  "overrides": [],
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaVersion": "latest",
    "sourceType": "module"
  },
  "plugins": ["react", "@typescript-eslint"],
  "rules": {
    "@typescript-eslint/no-empty-function": 0,
    "@typescript-eslint/no-empty-interface": 0,
    "react/prop-types": "off"
  }
}
```

#### prettierの設定ファイル作る
```sh
touch .prettierrc
```

こちらもお好みで設定を変えてください
```json:.prettierrc
{
  "tabWidth": 2,
  "useTabs": false,
  "semi": true
}
```


## viteインストール
```
npm i --save-dev vite @vitejs/plugin-react
```

#### vite.config.ts 作成
```ts:vite.config.ts
import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";

export default defineConfig({
  server: {
    open: true,
  },
  plugins: [react()],
});
```


#### package.jsonにコマンド追加
```json:package.json
  "scripts": {
    "serve": "vite preview",
    "dev": "vite",
    "build": "vite build",
    "build:dev": "vite build --mode development",
    "lint": "eslint lint src",
    "test": "echo \"Error: no test specified\" && exit 1"
  }
```

## 起動用のhtmlやtsxを作る
作るものリスト

- `./public/favicon`
- `./src/index.tsx`
- `./index.html`

#### ./public/favicon
faviconは別になくてもいいです！


#### src/index.tsx
`test`と表示するだけ

```tsx:src/index.tsx
import React from "react";
import ReactDOM from "react-dom/client";

const App = (): React.ReactNode => <div>test</div>;

ReactDOM.createRoot(document.getElementById("root")!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
);
```


#### index.html
適当にコンテンツ作ります
```html:index.html
<!doctype html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <title>react-typescript-base-project</title>
    <meta
      name="description"
      content="React × TypeScript × vite を利用したベースプロジェクトです"
    />

    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
    />

    <meta property="og:type" content="website" />
    <meta property="og:site_name" content="react-typescript-base-project" />
    <meta property="og:title" content="react-typescript-base-project" />
    <meta
      property="og:description"
      content="React × TypeScript × vite を利用したベースプロジェクトです"
    />
    <meta property="og:image" content="%PUBLIC_URL%/logo.svg" />
  </head>
  <body>
    <noscript>
      <strong>javascriptを有効にしてください</strong>
    </noscript>
    <div id="root" />
    <script type="module" src="/src/index.tsx"></script>
  </body>
</html>
```



## いざ起動！
```
npm run dev
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3340968/8a5ad02a-3abe-d108-fcd8-8d8f4747feb9.png)

ばっちりですね


## 最終的なディレクトリ構成
以下のようになっていればOKです

```
react-typescript-base-project
 ├─ node_modules
 │   └─ 各種ライブラリ（省略）
 │
 ├─ public
 │   └─ favicon.icon （任意）
 │
 ├─ src
 │   └─ index.tsx
 │
 ├─ .eslintrc.json
 ├─ .prettierrc
 ├─ index.html
 ├─ package-lock.json
 ├─ package.json
 ├─ tsconfig.json
 └─ vite.config.ts
```

## 最後に
本当にただ起動するだけです！
ここから先はご自由にどうぞ