СтихТок. Как я перестал «залипать» и начал духовно расти

в 5:55, , рубрики: pet-project
СтихТок. Как я перестал «залипать» и начал духовно расти - 1

Когда пришла эпоха коротких видео в TikTok и YouTube, я, как и многие, стал проводить там слишком много времени, порой обнаруживая себя засыпающим в 5 утра под листание бесконечной ленты. Тогда я решил отучить себя от этой привычки. Пробовал разные ограничения, но, в конечном итоге, просто забивал на них.

Примерно в это же время я увлёкся поэзией. Мне было около 30, когда я научился получать удовольствие от чтения стихов. И я подумал — а почему бы не заменить короткие видео на стихи. Тогда каждый раз, когда я хотел позалипать в тикток, я вместо этого открывал случайное стихотворение какого-нибудь автора, читал несколько стишков, закрывал, и возвращался к делам.

Если подумать, то стихи — это тиктоки 20 (19, 18 ...) века. Но красивое стихотворение вызывает более сильные чувства, чем любое короткое видео, и, что самое важное, к нему хочется возвращаться, перечитывать, и вновь получать удовольствие от красоты написанного. А особенно понравившиеся стихи, учить наизусть.

Так у меня появилась идея полушутя-полусерьезно сделать приложение с тикток механикой, но вместо видео — стихи.

Nocode VS Code

Я ничего не знал о фронтенд разработке и решил попробовать nocode-инструменты. 

Механика моего приложения элементарна — бесконечный скроллинг текста, поэтому я думал, что быстро накидаю готовые компоненты и в продакшен. На деле оказалось, что даже такую простую механику готовыми компонентами не реализовать. 

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

Зачем тогда вообще этот уровень абстракции? 

Если уж и изучать, то полноценный инструмент, который дает свободу творчества.

Всё-таки code

Так я начал смотреть в сторону React Native, но нашел еще более простое решение — PWA (progressive web app). Это технология, которая позволяет сделать приложение из обычного сайта. Сейчас многие банки, приложения которых недоступны в AppStore, используют эту технологию. PWA — это когда можно на смартфон «установить» сайт. На домашнем экране появится иконка приложения, если его запустить, то откроется сайт, но без интерфейса браузера. Как будто нативное приложение.

В Safari в меню Поделиться есть пункт “На экран Домой», который установит PWA на домашний экран. В Chrome на Android в контекстном меню есть пункт «Установить приложение»

В Safari в меню Поделиться есть пункт “На экран Домой», который установит PWA на домашний экран. В Chrome на Android в контекстном меню есть пункт «Установить приложение»

Конечно, многие функции в PWA-приложениях ограничены, ведь это просто сайт, но у меня простое веб-приложение, и PWA для него подходит идеально.

Backend

Бэкенд я сделал на DjangoRestFramework, потому что это быстро и удобно. Мне нужен простой API, в который я буду обращаться из JS-фронтенда. В качестве базы данных использую PostgreSQL.

Frontend

Для фронтенда я выбрал ReactJS, т.к. это самый распространённый фреймворк. Я никогда не писал на JS, поэтому учился этому с нуля, и то, что у ReactJS большое комьюнити, мне очень помогло в изучении. Если тоже начинаете изучение React, могу посоветовать вот этот бесплатный курс.

Чтобы из сайта сделать PWA-приложение, он должен соответствовать нескольким требованиям:

  • обязательный HTTPS

  • manifest с описанием

  • наличие service worker-а

Service worker — это js-код, который выступает посредником между приложением и интернетом, т.е. все запросы в API, которые будет отправлять приложение, будут отправляться через этот воркер.

Он может кэшировать их, обрабатывать ситуации плохой связи или её отсутствия, чтобы пользователь не увидел ошибку браузера, а увидел вашу собственную “заглушку”. Вообще, тема service worker-ов очень обширна, на Хабре можно найти подробные статьи об этом. Я же сгенерировал свой воркер в сервисе pwabuilder.com

Здесь я отключил интернет на смартфоне, и вместо браузерного ERR_NETWORK_ERROR, вижу собственное красивое сообщение об ошибке. За это отвечает service worker.

Здесь я отключил интернет на смартфоне, и вместо браузерного ERR_NETWORK_ERROR, вижу собственное красивое сообщение об ошибке. За это отвечает service worker.

После добавления воркера, выяснилось, что самая популярная JS-библиотека для HTTP-запросов axios, не умеет работать через него. Пришлось заменить axios на ky.

Ky работает через Fetch, поэтому подходит для использования с service worker.

Ky работает через Fetch, поэтому подходит для использования с service worker.

Проблема превью в мессенджерах

Мое приложение — это SPA на ReactJS, поэтому по GET запросу любой страницы веб-сервер возвращает пустой HTML, а дальше отображением занимается JS-код внутри браузера, изменяя DOM-дерево "на лету". И если, например, делиться ссылкой в Телеграме на какую-либо страницу сайта, то на превью будет якобы пустая страница, хотя внутри браузера у пользователя есть контент, но превью-генераторы не умеют рендерить JS, они просто посылают GET запрос, и на основе полученного пустого HTML рисуют превьюшку в чате. Та же ситуация и с поисковыми ботами Google и Яндекс.

Для решения этой проблемы, я нашел вот такой контейнер. Внутри headless chrome, который любезно срендерит JS за поискового бота или генератора превьюшек в мессенджерах. На входящем nginx-е я строю маршрутизацию запроса на основе заголовка User-Agent, и, если это поисковой бот или превью-генетатор, то проксирую этот запрос в пререндер-контейнер, который вернет HTML-страницу с отрисованным контентом.

Вот только я еще не решил — это изящное решение архитектурной проблемы, или ужасный костыль?

Перед публикацией статьи, увидел, что у поискового бота Яндекса появилась бета-версия "Рендеринга страниц JavaScript"

Deploy

Когда пришла пора деплоить приложение в прод, я купил домен stihtok.ru, и подыскал VPS-хостинг. Мне понравился TimeWeb Сloud, я взял самую дешевую виртуалку и сделал ansible-плейбуки для установки необходимого окружения на сервере.

Разумеется, все работает в докере. Для автоматизации сборки контейнеров я использую GitHub Actions с собственным раннером на сервере. По коммиту в ветку происходит сборка и деплой на тестовый стенд, а отведение тэга деплоит его на прод.

Вот такое получилось приложение:

Автор: Роман Орлов

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js