@hexlet/js-online-store-frontend
v1.0.0
Published
Фронтенд интернет-магазина комплектующих. Хекслет предоставляет его студенту-бекендеру: приложение работает поверх API, которое студент реализует по контракту.
Readme
frontend — готовый фронтенд для студента-бекендера
Интернет-магазин комплектующих на React + Mantine + Vite + TypeScript. Студент его не пишет — он подключает собранную сборку и реализует под неё API. Экраны: главная с промо-блоками, каталог с фильтрами и пагинацией, карточка товара, корзина, оформление заказа, регистрация и вход, личный кабинет с историей заказов.
Публикуется как npm-пакет @hexlet/js-online-store-frontend, в пакет уезжает только dist.
Команды
make install # npm install
make build # tsc + vite build → dist/
make dev # дев-сервер на :5173, проксирует /api на $API_URL (дефолт http://localhost:8080)
make types # перегенерировать src/schema.js из ../contract/openapi.yaml
make publish # npm publish (вручную, нужен токен)Как он попадает в приложение
code/package.json зависит от этого пакета, make -C code build копирует его dist в public/,
откуда статику раздаёт сервер студента. Запросы идут по относительным путям /api/... — тот же
origin, что и приложение; абсолютного адреса API в сборке нет. Сессия живёт в httpOnly-cookie,
запросы уходят с credentials: 'same-origin'.
Пока пакет не опубликован в npm, зависимость указана как file:../frontend — npm подставляет
локальный каталог симлинком. После публикации это меняется на версию из реестра одной строкой в
code/package.json, и тогда обязательно удалить code/package-lock.json: иначе npm видит запись на
локальный каталог, её версия удовлетворяет диапазону, и симлинк тихо остаётся.
Ссылки на ADR в комментариях
Код перенесён из projects/ru/frontend_online_store_project (там магазин пишет студент-фронтендер), и
комментарии ссылаются на решения вида «(ADR 0011)». Эти документы живут в том проекте, в
docs/adr/, — здесь их нет намеренно: дублировать журнал решений в двух репозиториях значит завести
второй источник правды. Ссылки оставлены как след: по номеру решение находится в исходном проекте.
Типы клиента
src/schema.js — сгенерированный артефакт цепочки TypeSpec → OpenAPI → TypeBox
(@geut/openapi-box, пакета openapi-box в npm не существует). Он коммитится, чтобы сборка не
зависела от тулчейна контракта, и пересобирается целью make types из ../contract/openapi.yaml.
Руками его не правят: расхождение фронтенда с контрактом должно быть ошибкой компиляции.
Тексты интерфейса
Тексты лежат в src/locales/ru/translation.json, а собирает этот файл i18next-cli из вызовов
t (make i18n-extract, настройки — i18next.config.ts). Объявления ресурсов в src/@types
генерирует make i18n-types. И то и другое коммитится и руками не правится.
Ключ передаётся селектором, а не строкой: t(($) => $.nav.catalog). Путь проверяет компилятор,
поэтому опечатка не доживает до экрана. Ключи, которые собираются по данным (тексты ошибок по
problem.type), объявлены селекторами в словарях — lib/problems.ts; статически их не видно,
и в i18next.config.ts они перечислены в preservePatterns, иначе extract вычистил бы их как
неиспользуемые.
Чего здесь намеренно нет
- Мониторинга фронтенда. Vite подставляет
VITE_*на сборке, а собираем этот пакет мы — студент свой DSN сюда не запечёт. Мониторинг в проекте требуется только от бэкенда. - Любой реализации API. Всё, что фронт знает о бэкенде, — контракт: относительные пути
/api/*и формы ответов. Готового решения задачи бекендера в этом каталоге быть не должно.
