🥷

React (Vite) + Spring Boot (Kotlin) プロジェクトの初期設定

2023/08/04に公開

この記事は何ですか?

新規にウェブアプリケーションを React (フロントエンド) と Spring Boot (バックエンド) で構築したときの初期設定に関するメモです。特に React の設定について焦点を置いて記述します。Spring Boot は枯れた Spring Initializr で容易に設定できる一方、React 関連の設定はトレンドの移り変わりが激しいためです。なお、この記事では Vite で React の設定をします。

本記事の通りに設定すると、次のようなディレクトリ構成になります。frontend/ には React アプリケーションがあり backend/ には Spring Boot アプリケーションがある、というイメージです。

$ tree .
.
├── README.md
├── backend
│   ├──... 
│   ...
└── frontend
    ├── ...
    ...

frontend/ を作る

新規プロジェクトに frontend/ ディレクトリを作り、そこに React プロジェクトを配置します。

Vite でプロジェクトの雛形を作る

次のコマンドでプロジェクトの雛形を作れます。

$ npm create vite@latest frontend -- --template react-ts
$ cd frontend
$ npm install

これで React の実行に必要なパッケージがインストールされます。続けて npm run dev とすると React が立ち上がり、http://localhost:5173 でリクエストを受け付けます。

Vite でテストを実行する

Vitest を追加でインストールします。

$ npm install --save-dev vitest

あわせて package.json の scripts に "test": の項を足します。次のようになります。

...
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
    "preview": "vite preview",
    "test": "vitest run"   <-- 追加
  },
...

これで npm test で Vitest が起動します。

Vite で React コンポーネントのテスト を実行する

React コンポーネントをテストするには、もう少し設定が必要です。

React コンポーネントをレンダリングしたり、便利なマッチャーを利用するため、次のようにライブラリを追加でインストールします。

$ npm install --save-dev jsdom @testing-library/react @testing-library/jest-dom @testing-library/user-event jest-extended

続けて vite.config.ts を次のように書き換えます。

/// <reference types="vitest" />

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  test: {
    globals: true,
    environment: 'jsdom',
    setupFiles: './src/setup.ts',
  },
})

./src/setup.ts には次の二行を記述します。

import '@testing-library/jest-dom/extend-expect'
import 'jest-extended';

これで jsdom 環境に React コンポーネントを描画したり、イベントを発行したり、内容をアサートできるようになります。

試しに、標準で提供される App.tsx をテストするため、次のような App.test.tsx を書けます。

import { describe, it } from 'vitest'
import { render, screen } from '@testing-library/react'
import App from './App'

describe('App', () => {
    it("はじめての Vitest", () => {
        render(<App />)
        expect(screen.getByText("Click on the Vite and React logos to learn more")).toBeInTheDocument();
    });
})

backend/ を作る

Spring Initializr で適当なプロジェクトを作ります。ここではプログラミング言語として Kotlin を選択し、Dependencies に Spring Web を含めていると仮定しています。

生成されたプロジェクトを解凍して backend/ という名前でプロジェクトのルート直下に置きます。先に作成した frontend/ との連携確認のため、このプロジェクトにダミーの API エンドポイントを作成します。次のようなコントローラーを作ります。

package com.example.demo

import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

data class Demo(val name: String)

@RestController
@RequestMapping("/api/v1/demo")
class DemoController {
    @GetMapping
    fun demo(): Demo {
        return Demo("ケンシロウ")
    }
}

この状態で Spring Boot を起動すると http://localhost:8080/api/v1/demo へのリクエストに { "name": "ケンシロウ" } という JSON が返るようになります。

Proxy を設定する

frontend/ のプロジェクトから backend/ プロジェクトへのリクエストは、ポート番号の違いからクロスオリジンになります。特別な理由がない場合、クロスオリジンリクエストは許可しない方が望ましいです。ここでは frontend/ に Proxy を設定することで対応しましょう。

具体的には vite.config.ts に次の設定を追加します。

...
  server: {
    proxy: {
      "/api": {
        target: "http://localhost:8080",
        changeOrigin: true,
        secure: false,
      }
    }
  }
...

念のため、先に設定したものとあわせて全体の vite.config.ts を掲載します。

/// <reference types="vitest" />

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  test: {
    globals: true,
    environment: 'jsdom',
    setupFiles: './src/setup.ts',
  },
  server: {
    proxy: {
      "/api": {
        target: "http://localhost:8080",
        changeOrigin: true,
        secure: false,
      }
    }
  }
})

ここまですれば React と Spring Boot を組み合わせた開発をはじめられます。

細々としたところではリンターや CI/CD であったり CSS フレームワークの組み込みなどもありますが、それらについてはウェブ上にリファレンスがたくさんあるので、ここでは扱いません。

GitHubで編集を提案

Discussion