Фронтенд проекта Shortstories

Для начала расскажу о проекте. Shortstories — это open source платформа для чтения и написания любительских рассказов. Делаю я этот проект в одиночку и здесь хочу рассказать о том как устроен фронтенд. Сайт можно посмотреть здесь:

Фронтенд я реализовывал дважды. Первый раз, когда только начал делать проект, второй раз после полугодовой паузы. Первая версия состояла из create-react-app, redux, redux-thunk, стили в CSS. Всё просто: отправка запросов в thunk’ах к REST API, хранение ответов в redux store. При таком подходе не было server side rendering'a (SSR), который для моего проекта важен из-за SEO продвижения. Также пришлось переписывать большую часть компонентов, потому что бэкэнд был переписан GraphQL.

Я не стал писать велосипед и за основу проекта взял Next.js, он поддерживает SSR из коробки. Интеграция с GraphQL API происходила посредством библиотеки react-apollo, которая является некой прослойкой между бэком и фронтом. Стили переписал на styled-components, просто потому что привык. Но не советую брать эту либу, если у ваших клиентов низкая скорость интернета, styled-components тянет лишние 30 кб js кода для генерации стилей. Если для вас это критично возьмите astroturf или linaria.

После переписывания сайт стал работать быстрее, потому что почти все запросы выполнялись на сервере, а html со стилями отдавался моментально. Также я был приятно удивлен упрощением разработки: не нужно вручную обрабатывать состояния отправки запроса (loading, error), реализация optimistic UI делается в пару строк кода.

Но не все так гладко. Я столкнулся с несколькими проблемами. Компоненты в react-apollo используют паттерн render props, поэтому если у нас в компоненте несколько мутаций (аналог POST/PUT запроса), то падает читабельность. Решить это можно, используя либу react-adopt. Также есть проблемы с кэшем — обновлять его надо вручную и следить, чтобы он обновлялся корректно.

Код можно посмотреть здесь:

Буду признателен если проведете код-ревью или поучаствуете в разработке.

11
Начать дискуссию