раздел 05 · шаг 3/7
Шаг 3. React + Vite + Tailwind
Поднимаем фронт. Vite даёт быстрый dev-server, React 19 + TypeScript - типизированный UI, Tailwind 4 - стили без CSS-файлов, TanStack Query - кеш и состояние запросов.
Что делаем
- Создаём проект во
frontend/через Vite - Настраиваем Tailwind 4
- Поднимаем минимальный UI: список задач с инлайн-добавлением
- Запускаем dev, видим заготовку
Промпт для Claude
Создай frontend во frontend/ на Vite + React 19 + TypeScript + Tailwind 4 + TanStack Query.
Стек:
- Vite (без SWC, обычный esbuild)
- React 19, TypeScript 5
- Tailwind CSS 4 (через @tailwindcss/vite плагин, без отдельного tailwind.config.js если можно)
- @tanstack/react-query 5 для fetch и кеша
- Без UI-библиотек - всё на кастомных компонентах с Tailwind
UI:
- Главная страница - список задач
- Инлайн-добавление сверху: input + Enter создаёт задачу через POST /api/tasks
- Каждая задача - строка с чекбоксом, заголовком, бейджем категории, кнопкой удалить
- Dark theme: фон bg-zinc-950, текст zinc-100
- Акценты эмеральд: emerald-400 для активных элементов, emerald-500 для кнопок
- Минимализм, без скругления больше rounded-lg, без теней
- Адаптив под мобилу
Backend живёт на http://localhost:8000.
Сделай util fetchApi с базовым URL и обработкой ошибок.
Используй QueryClient с дефолтным staleTime 30 сек.
Запиши команды запуска в frontend/README.md и в корневой README.md.
Что Claude создаст
Структура:
frontend/
├── public/
├── src/
│ ├── App.tsx # главная страница
│ ├── main.tsx # точка входа, QueryClientProvider
│ ├── index.css # @import "tailwindcss"
│ ├── lib/
│ │ └── api.ts # fetchApi util
│ ├── components/
│ │ ├── TaskList.tsx
│ │ ├── TaskItem.tsx
│ │ └── TaskInput.tsx
│ └── types.ts # временные типы (на шаге 4 заменим)
├── index.html
├── package.json
├── tsconfig.json
├── vite.config.ts # с @tailwindcss/vite
└── README.md
package.json должен содержать:
{
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"preview": "vite preview"
},
"dependencies": {
"react": "^19.0.0",
"react-dom": "^19.0.0",
"@tanstack/react-query": "^5.0.0"
},
"devDependencies": {
"@tailwindcss/vite": "^4.0.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"@vitejs/plugin-react": "^4.3.0",
"tailwindcss": "^4.0.0",
"typescript": "^5.6.0",
"vite": "^6.0.0"
}
}
Устанавливаем зависимости
cd frontend
pnpm install
Запуск
pnpm dev
В терминале:
VITE v6.0.0 ready in 234 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
Открываете http://localhost:5173. Видите заготовку: тёмный фон, поле ввода, пустой список.
Первая проверка работы
Включите бэк в одном терминале (uvicorn app.main:app --reload), фронт в другом (pnpm dev).
Вбейте в поле ввода "купить молоко", нажмите Enter. Задача должна:
- Уйти POST-запросом на
http://localhost:8000/api/tasks - Вернуться в ответе с id и created_at
- Появиться в списке через invalidate query
Если CORS-ошибка - значит, на шаге 2 бэк настроен на неправильный origin. Откройте backend/app/main.py, проверьте что в allow_origins есть http://localhost:5173.
скриншот
Что НЕ работает на этом шаге
- Бэйджи категорий показывают только
other- категоризация будет на шаге 5 - TS-типы написаны руками (
types.ts) - на шаге 4 заменим на сгенерированные - Нет состояний loading/error - тоже на шаге 4
- Нет тестов - шаг 6
Сейчас задача - чтобы пользовательский поток работал. Чистоту наводим дальше.
Точка сохранения
cd ..
git add .
git commit -m "step 3: React + Vite + Tailwind frontend, basic task list"
Полезные ссылки
- Vite docs - конфиг и плагины
- Tailwind CSS 4 - новая версия с Vite-плагином
- TanStack Query - паттерны кеширования