1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Viteで始める高速Web開発 | 第7章: TypeScriptとテストで強化

Posted at

はじめに

第6章でバックエンドと連携しました。今回は、TypeScriptでコードを安全にし、Vitestでテストを追加します。これでアプリの信頼性と保守性が向上します。

目標

  • TypeScriptをViteに統合する
  • Vitestでユニットテストを実装する
  • ToDoアプリを強化する

TypeScriptの導入

1. TypeScriptプロジェクトへの移行

既存プロジェクトをTypeScriptに変換:

npm install typescript @types/react @types/react-dom --save-dev
  • プロジェクト作成時に--template react-tsを選んだ場合は不要。

tsconfig.jsonがなければ、生成:

npx tsc --init

vite.config.jsvite.config.tsに変更:

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/, ''),
      },
    },
  },
});

2. App.tsxへの変換

src/App.jsxsrc/App.tsxにリネームし、型を追加:

import { useState, useEffect } from 'react';
import './App.css';

interface Todo {
  id: number;
  text: string;
}

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

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

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

  const addTodo = async (e: React.FormEvent) => {
    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: Todo = 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;

Vitestの導入

1. インストール

npm install vitest jsdom @testing-library/react @testing-library/jest-dom --save-dev

2. 設定

vite.config.tsにテスト設定を追加:

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/, ''),
      },
    },
  },
  test: {
    environment: 'jsdom',
    globals: true,
    setupFiles: './src/test/setup.ts',
  },
});

src/test/setup.tsを作成:

import '@testing-library/jest-dom';

package.jsonにスクリプトを追加:

"scripts": {
  "test": "vitest"
}

3. テストの実装

src/App.test.tsxを作成:

import { render, screen, fireEvent } from '@testing-library/react';
import App from './App';

describe('App', () => {
  it('タスクを追加できる', async () => {
    render(<App />);
    await screen.findByText('私のToDoアプリ'); // タイトルが表示されるまで待機

    const input = screen.getByPlaceholderText('タスクを入力');
    const button = screen.getByText('追加');

    fireEvent.change(input, { target: { value: 'テストタスク' } });
    fireEvent.click(button);

    expect(await screen.findByText('テストタスク')).toBeInTheDocument();
  });
});
  • バックエンド依存のため、モックが必要な場合も考慮。

動作確認

  • TypeScript: npm run devでエラーがないか確認。
  • テスト: npm testでテストを実行。

次回予告

第8章でシリーズを総括し、次の学習ステップを提案します。お楽しみに!


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

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?