[RITA] React + Inertia + TypeScript + Adonis構成を作成する

# 概要
Laravel LikeなFullstack TypeScript Frameworkを試してみる。
Inertia v1 + Adonis + React + Typescript

# CSR

## インストール

yarnですすめます。

```bash
yarn create adonis-ts-app .
```

```bash
yarn create v1.22.17
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...
success Installed "create-adonis-ts-app@4.2.4" with binaries:
      - create-adonis-ts-app

     _       _             _         _ ____  
    / \   __| | ___  _ __ (_)___    | / ___| 
   / _ \ / _` |/ _ \| '_ \| / __|_  | \___ \ 
  / ___ \ (_| | (_) | | | | \__ \ |_| |___) |
 /_/   \_\__,_|\___/|_| |_|_|___/\___/|____/ 
                                             


CUSTOMIZE PROJECT
❯ Select the project structure …  Press <ENTER> to select
❯ api   (Tailored for creating a REST API server)
  web   (Traditional web application with server rendered templates)
  slim  (A smallest possible AdonisJS application)
```

インストール完了するとカラフルにcliで色々効かれる。
今回は webにして後全部yesにしました。

```bash
CUSTOMIZE PROJECT
❯ Select the project structure · web
❯ Enter the project name · test
❯ Setup eslint? (y/N) · true
❯ Setup prettier? (y/N) · true
❯ Configure webpack encore for compiling frontend assets? (y/N) · true
```

## 起動確認

ここまででひとまず起動を確認します

```bash
node ace serve --watch         
```

問題なく起動しています。

![スクリーンショット 2023-05-27 4.20.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174757/79797cd1-552e-df39-2146-5e0fedec3e17.png)


# Inertia + React + Typescript導入 (SPA)

inertiaのadonis providerを使います。

https://github.com/eidellev/inertiajs-adonisjs

インストールして

```bash
yarn add @eidellev/inertia-adonisjs
```

必須なライブラリとその設定をします
選択で出るものはbrowserのまま

```bash
yarn add @adonisjs/view
yarn add @adonisjs/session

node ace configure @adonisjs/view
node ace configure @adonisjs/session
```

構成をしてくれるコマンドを実行します

```bash
node ace configure @eidellev/inertia-adonisjs
```

ひとまずSSRはなしにしておきます

```bash
 node ace configure @eidellev/inertia-adonisjs
❯ Enter the `.edge` view file you would like to use as your root template · app
❯ Would you like to use SSR? (y/N) · false
❯ Which client-side adapter would you like to set up? · @inertiajs/react
[ wait ]  Installing dependencies: @inertiajs/react, react, react-dom, @types/react, @types/react-dom . 
```

これでreact関連とinertia関連が入りました

次にkernel.tsにミドルウェア設定を追加します

```diff_javascript:kernel.ts
- Server.middleware.register([() => import('@ioc:Adonis/Core/BodyParser')])
+ Server.middleware.register([
+   () => import('@ioc:Adonis/Core/BodyParser'),
+   () => import('@ioc:EidelLev/Inertia/Middleware'),
+ ]);
```

app.jsをapp.tsxに変更して、内容を下記にします

```ts:app.tsx
import { createRoot } from 'react-dom/client'
import { createInertiaApp } from '@inertiajs/react'

createInertiaApp({
  id: 'app',
  resolve: (name) => require(`./pages/${name}`),
  setup: ({ el, App, props }) => createRoot(el).render(<App {...props} />),
})
```

tsconfig.jsonにオプションを追記します

```json:tsconfig.json
"compilerOptions": {
    "lib": ["dom"],
    "jsx": "react-jsx",
```

そして、`app.tsx`と同じ階層に`pages`ディレクトリと`tsconfig.json`を作ります。

`tsconfig.json`の内容は下記

```json:resources/js/tsconfig.json
{
  "include": ["./*"],
  "compilerOptions": {
    "target": "ES2015",
    "lib": ["dom"],
    "jsx": "react-jsx",
    "esModuleInterop": true,
    "moduleResolution": "node",
    "types": [
      "@eidellev/inertia-adonisjs"
    ]
  }
}

```


次に`webpack.config.js`にてreact、ts、エントリファイルの修正を記載します

```diff_javascript:webpack.config.js
- Encore.addEntry('app', './resources/js/app.js')
+ Encore.addEntry('app', './resources/js/app.tsx')
+ Encore.enableTypeScriptLoader()
+ Encore.enableReactPreset()
```

コンパイルに必要なものを入れます。

ちなみに`node ace serve`をすると

以下のようにこれいれろよーと警告してくれる

```
[ encore ] Running webpack-dev-server ...
  Error: Install @babel/preset-react to use enableReactPreset()  39m
    yarn add @babel/preset-react@^7.0.0 --dev

[ encore ] Running webpack-dev-server ...
  Error: Install ts-loader to use enableTypeScriptLoader()
    yarn add ts-loader@^9.0.0 --dev
```

必要なのは以下２つ

```bash
yarn add @babel/preset-react@^7.0.0 ts-loader@^9.0.0 --dev
```

`config/shield.ts`でEnvを使用していないけどimportしてるので`tsconfig.json`で`noUnusedParameters`を設定するか、`_`から始まるようにします

```js
// 修正案1 (tsconfig.json)
  "compilerOptions": {
    "noUnusedParameters": true,

// 修正案2 (config/shield.ts)
import _Env from '@ioc:Adonis/Core/Env'
```

この状態で`node ace serve`すると

正常に起動するはずです。


動作確認します。
ルーティングを追加して

```typescript:routes.ts
Route.get('/test', async ({ inertia }) => {
  return inertia.render('test', { name: 'adonis' })
}).as('test')
Route.get('/test2', async ({ inertia }) => {
  return inertia.render('test2', { name: 'adonis2' })
}).as('test2')
```

`pages`に`test`と`test2`を作ります

```tsx:pages/test
import { Link } from '@inertiajs/react'

const Test = ({ name }) => (
  <div>
    Hello world, {name}!
    <p>
      go to <Link href="test2">test</Link>
    </p>
  </div>
)

export default Test
```

```tsx:pages/test2
import { Link } from '@inertiajs/react'

const Test2 = ({ name }) => (
  <div>
    Hello world, {name}!
    <p>
      go to <Link href="test2">test</Link>
    </p>
  </div>
)

export default Test2
```

これで読み込み無しで遷移していれば問題なくCSRでのInertia React TS環境ができました。

ちなみにSSRは無限にバグって無理でした