[Дневник разработки] #2. Техническая часть и стек
В этой статье расскажу, на чём строится Invaiti, какие технологии использую и почему именно они. Пост будет полезен тем, кто интересуется современным фронтендом и хочет понять, как устроен проект изнутри — без лишней теории, только практический взгляд.
Frontend
С самого начала решил, что UI и взаимодействие — это ключевое в моём проекте. А значит, нужен фреймворк, который позволит быстро и понятно строить интерактивный интерфейс.
- Vue 3 + Composition API (TS) — потому что читаемо, масштабируемо и приятно писать. Я получаю гибкость и контроль без перегруза.
- Pinia + PiniaColada + Axios — для лёгкого и декларативного управления состоянием. PiniaColada помогает кешировать запросы и хорошо ложится в архитектуру Composition API.
- VueUse — удобнейший набор полезных хуков, без которого я уже не представляю себе разработку.
- UnoCSS — Я отказался от Tailwind в пользу Uno — он быстрее, легче и даёт больше контроля. Классы применяются моментально, без генерации огромных CSS-файлов; поддерживает кастомные токены, пресеты, темизацию. Отлично сочетается с Vue и даёт свободу в дизайне без ощущения «бойся трогать CSS».
- Iconify — универсальный способ подключения иконок. Можно легко использовать любую коллекцию (Material, Tabler, Fluent и др.) и на лету менять стиль, цвет, отлично дружит с UnoCSS.
- Naive UI — кастомизируемая компонентная библиотека, легко стилизуется под нужный стиль.
- Zod — использую для строгой валидации данных: форм, API-ответов и схем. Удобно типизируется, работает отлично в связке с TypeScript, и позволяет быстро ловить ошибки ещё до рендера.
- Lodash — потому что удобные утилиты для работы с массивами и объектами — это всегда +10 к чистоте кода.
- Vite — быстрый сборщик с хорошей интеграцией с Vue 3.
Backend
Вместо того, чтобы писать свой бэкенд с нуля, я выбрал Appwrite как backend-as-a-service:
- Удобная работа с коллекциями, документами и файлами.
- Готовая авторизация и безопасность из коробки.
- Быстрый старт — REST API (планирую переезд на GraphQL пока это еще не сильно напряжно) без лишнего, всё по делу.
Мне важно было быстро запустить прототип, и Appwrite дал возможность не застревать на инфраструктуре.
Инфраструктура
Проект развернут на VPS (на данный момент 4 x 3.3 ГГц CPU • 8 ГБ RAM • 80 ГБ NVMe), где крутится всё: фронт, Appwrite, GitLab.
- Свой GitLab CE с CI/CD пайплайнами и репозиториями.
- Фронтенд разбит на три контейнера:
dev
— основная ветка разработки.dev-2
— для экспериментов, обкатки фичей, работы с UI.- В скором времени планирую запустить
alpha
- сборка с MVP проекта, которым уже можно будет пользоваться по назначению. - Бэкапы всех сервисов автоматизированы и регулярно выгружаются.
Почему не Nuxt / Tailwind / Firebase?
- Nuxt — пока не нужен SSR и не хочется лишней магии.
- Tailwind — слишком тяжёлый для проекта, сложности в сборке и кастомизации.
- Firebase — мощный, но избыточный, а мне хотелось SelfHosted + REST/GraphQL, а не SDK с обвязками.
На что делаю упор в архитектуре
- Чистый код и логическая разделённость слоёв.
- Компоненты — маленькие и переиспользуемые.
- Сторы — изолированы и читаемы, храню в них только вспомогательную информацию, никаких данных.
- Работа с API — через универсальные обёртки, чтобы не размазывать логику по компонентам.
Без вайб-кодинга
В Invaiti я стараюсь избегать «вайб-кодинга» — когда решения принимаются по наитию, без чёткого плана, архитектуры или обоснований, когда ты полагаешься на AI или генераторы настолько, что перестаёшь принимать решения осознанно и развивать себя как разработчика. Такой подход может быть забавным на пет-проектах, но в реальном продукте он быстро приводит к хаосу.
- предсказуемую структуру кода, чтобы и я, и любой новый разработчик могли быстро разобраться;
- разделение ответственности: компоненты, сторы, API, утилиты — всё отдельно;
- логичные имена, минимальный кросс-импорт и максимум читаемости.
Если пишу компонент — то стараюсь сразу представить, как его протестировать, переиспользовать и изменить через месяц.
Проект должен быть живым и читаемым через полгода, а не только вечером в пятницу