Viteで始める高速Web開発 | 第6章: Viteとバックエンドの連携

## はじめに
第5章でViteアプリをデプロイしました。今回は、バックエンドと連携し、ToDoリストのデータをAPIから取得・保存します。Node.jsとExpressを使った簡単なバックエンドを用意します。

## 目標
- ViteでバックエンドAPIを呼び出す  
- 開発時のプロキシを設定する  
- ToDoデータをサーバーに保存する  

## バックエンドの準備
### 1. プロジェクト作成
新しいフォルダ`backend`を作成：
```bash
mkdir backend
cd backend
npm init -y
npm install express
```

### 2. 簡単なAPIの実装
`backend/index.js`を作成：
```javascript
const express = require('express');
const app = express();
const port = 5000;

app.use(express.json());

let todos = [
  { id: 1, text: 'サンプルタスク' },
];

app.get('/todos', (req, res) => {
  res.json(todos);
});

app.post('/todos', (req, res) => {
  const { text } = req.body;
  const newTodo = { id: Date.now(), text };
  todos.push(newTodo);
  res.status(201).json(newTodo);
});

app.listen(port, () => {
  console.log(`Server running at http://localhost:${port}`);
});
```
起動：
```bash
node index.js
```
`http://localhost:5000/todos`でデータが確認できます。

## Viteでのプロキシ設定
開発中、CORSを回避するため、Viteのプロキシを使用します。`vite.config.js`を更新：
```javascript
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:5000',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, ''),
      },
    },
  },
});
```
- `/api/todos`へのリクエストが`http://localhost:5000/todos`に転送。

## ReactでのAPI連携
`src/App.jsx`を更新：
```jsx
import { useState, useEffect } from 'react';
import './App.css';

function App() {
  const [todos, setTodos] = useState([]);
  const [input, setInput] = useState('');
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetchTodos();
  }, []);

  const fetchTodos = async () => {
    try {
      const response = await fetch('/api/todos');
      const data = await response.json();
      setTodos(data);
    } catch (error) {
      console.error('エラー:', error);
    } finally {
      setLoading(false);
    }
  };

  const addTodo = async (e) => {
    e.preventDefault();
    if (!input) return;

    try {
      const response = await fetch('/api/todos', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ text: input }),
      });
      const newTodo = await response.json();
      setTodos([...todos, newTodo]);
      setInput('');
    } catch (error) {
      console.error('追加エラー:', error);
    }
  };

  if (loading) return <div>読み込み中...</div>;

  return (
    <div className="App">
      <header>
        <h1>{import.meta.env.VITE_APP_TITLE}</h1>
      </header>
      <main>
        <form onSubmit={addTodo}>
          <input
            type="text"
            value={input}
            onChange={(e) => setInput(e.target.value)}
            placeholder="タスクを入力"
          />
          <button type="submit">追加</button>
        </form>
        <ul>
          {todos.map((todo) => (
            <li key={todo.id}>{todo.text}</li>
          ))}
        </ul>
      </main>
    </div>
  );
}

export default App;
```

## 本番環境での調整
デプロイ時、環境変数でAPI URLを指定：
- `.env`に追加：
  ```
  VITE_API_URL=https://your-backend-url
  ```
- `fetch`を修正：
  ```jsx
  const apiUrl = import.meta.env.VITE_API_URL || '/api';
  const response = await fetch(`${apiUrl}/todos`);
  ```

バックエンドもHerokuなどにデプロイし、CORSを設定：
```javascript
const cors = require('cors');
app.use(cors({ origin: 'https://my-vite-react.vercel.app' }));
```

## 動作確認
1. バックエンドを起動（`node index.js`）。
2. Viteを起動（`npm run dev`）。
3. `http://localhost:3000`でタスクが取得・追加できるか確認。

## 次回予告
第7章では、TypeScriptやテストを追加し、アプリをさらに強化します。お楽しみに！

---

この記事が役に立ったら、ぜひ「いいね」や「ストック」をお願いします！質問や感想はコメント欄で気軽にどうぞ。次回も一緒に学びましょう！