lezvieprod

Об этом сайте - технологии, подходы и программные решения

В этой статье я расскажу о том, что использовал при разработке lezvieprod.ru, с какими трудностями сталкивался и какими идеями руководствовался.

Предисловие

В первую очередь стоит заметить, что сайт не использует CMS или другие подобные решения. За основу был взят фреймворк Next.js + TypeScript.

Этап №1. Начало разработки. Авторизация, регистрация

На старте было принято решение сперва реализовать авторизацию в приложении. Для управления JWT использовал библиотеку jose.js, а качестве базы данных решил использовать реляционную систему - MySQL. Для облегчения работы с БД выбрал ORM - Prisma.js.

В тот момент только-только вышел Next 12 поэтому я решил использовать новую возможность фреймворка а именно middleware. В них я хотел использовать преимущественно проверку на права пользователя и управление кукисами. К сожалению вышло не так гладко как хотелось, приложение вело себя крайне нестабильно в процессе авторизации. Вход в аккаунт мог быть произведен как с первого раза так и с пятого, а также постоянно вылазила ошибка хот релоада webpack-dev-server. Посидев над этой проблемой чуть больше недели, я пришел к выводу, что middleware не подойдет для моих целей, тем более что фича еще была в экспериментальном режиме. Отказ от middleware, существенно ускорил ход разработки и через некоторое время в приложении была реализована полноценная система авторизации.

В целом, авторизация представляет собой разделение прав пользователей с возможностью продолжения сессии. Таким образом, каждый пользователь на старте получает дефолтную группу с правами пользователя. Всего реализовано 5 групп: пользователь, редактор, модератор, администратор, главный администратор. Изначально я хотел сделать группы динамичной составляющей. То есть сделать так, чтобы группы можно было добавлять прямо из админ панели, однако, чуть позже я отказался от этой идеи, в пользу ускорения разработки. Для продолжения сессии используется refresh token, который лежит в базе данных. При истечении срока действия access token осуществляется запрос на обновление сессии, в процессе которого происходит обновление обоих токенов.

Таблица сессий в базе данных<br>
Таблица сессий в базе данных

Этап №2. Компоненты, Redux, анимации

Компоненты

Еще на стадии задумки проекта, я решил отказаться от библиотек стилизации таких как Chakra UI, Material UI или Bootstrap. Однако не обошелся без либы react-icons.

В ходе разработки, я создал свой набор переиспользуемых компонентов. Замечу, что создание собственных компонентов существенно замедлило  процесс, однако, это дало большую свободу действий: без лишних проблем я мог дописать или переписать компонент под разные нужды.

Использование компонента SidebarMenu
Использование компонента SidebarMenu

Управление глобальным состоянием

В роли стейт менеджера я стал использовать то, с чем знаком, а именно Redux Toolkit. В дополнение к нему принял решение установить next-redux-wrapper, так как необходимо было управлять состоянием контента подгруженного с помощью SSR. Для получения и кэширования данных использовал встроенный в тулкит инструмент RTK Query. 

Анимации

Для построения анимаций я стал анализировать библиотеки framer-motion и react-spring. Первая мне показалась удобной и легкой, по сравнению со второй, однако, размер либы оставлял желать лучшего, несмотря настраиваемый code splitting. Вторая же имеет более высокий порог входа, но предлагает большую гибкость в настраивании анимациий, да и размер не такой большой. В итоге выбрал вторую.

Этап №3. Управление приложением, ПУ

Для администраторов была реализована панель управления, где, на момент написания статьи, можно редактировать и удалять пользователей и посты. Помимо ПУ, на сайте есть возможность редактировать посты с помощью выпадающего меню.

Выпадающее меню, вызываемое нажатием на троеточие<br>
Выпадающее меню, вызываемое нажатием на троеточие

Этап №4. Добавление и редактирование публикаций

Написание публикаций происходит в модальном окне, в котором подгружается редактор Editor.js написанный талантливыми разработчиками из команды CodeX. Такой же редактор используется на сайтах DTF и VC.

Модальное окно для написания публикации<br>
Модальное окно для написания публикации

При любом изменении контента происходит автосохранение поста с небольшой задержкой, защищающей от спама запросов. Несмотря на то, что я раньше сам писал такие задержки, для этого проекта я использовал хук из библиотеки use-debounce.

Этап №5. Пользователи, статус онлайн

После регистрации, каждый пользователь получает свой профиль, в котором, на момент написания статьи, информации крайне мало. Для просмотра доступен лишь логин и статус "в сети".

Определение статуса пользователя происходит таким образом: как только авторизованный пользователь попадает на любую страницу приложения то запускается таймер, который раз в двадцать секунд отправляет запрос на обновление статуса. Каждый раз таймер будет останавливаться при достижении 4 таких запросов. Если будет осуществлен переход на другую страницу таймер запустится заново и будет отсчитывать 4 запроса.

Этап №6. Мессенджер. Сокеты

Ранее я уже писал отдельное приложение на сокетах, однако, там использовалась MongoDB, которая перестала работать в России. Соответственно, -1 проект из моего портфолио, который надо как-то компенсировать.

В этом приложении я решил сделать мессенджер, который будет хоть немного похож на современные аналоги.

Было реализовано: автоматическая подгрузка сообщений при скроллинге вверх, удаление, редактирование, копирование сообщений, удаление всех сообщений администратором сайта, автоматические сообщения, статус сообщения (прочитано/отправлено), адаптивность для мобильного телефона.

Пример использования мессенджера
Пример использования мессенджера

Этап №7. Сервер для статических файлов

Изначально для этого приложения я стал использовал облачный сервис Cloudinary, однако после случая с MongoDB, понял что это может быть фатально в будущем. Таким образом, мне требовался сервер, на который можно будет загружать картинки и который будет отдавать эти картинки в виде статики.

Для статического сервера я стал использовать Express + TypeScript, в общем то, с чем я был знаком ранее. Логика сервера устроена так, что когда пользователь загружает картинку, сервер создает две копии: одну заблюренную, другую оригинальную. Далее отдает размер и ссылку на эту картинку обратно на клиент.

Этап №8. SEO, метатеги, редиректы

Для работы с поисковой оптимизацией я использовал встроенный в Next компонент next/head. Указал разметку Open Graph, канонические ссылки и другие полезные метатеги.

На странице с постом, в случае если был введен не верный slug title в url, будет происходить редирект на корректный. Каноническая ссылка также защищает поисковик от ссылок, которые ведут на одну и ту же публикацию.

Заключение

В заключение добавлю, что по мере разработки приложения статья будет дополняться. Спасибо за внимание!