Решил ознакомиться с темой статических сайтов и сделать небольшой decoupled (он же headless) Drupal сайт с фронт-ендом, полностью написанным на React — https://z-portfolio.tk.
Изначально для реализации задуманного я выбрал Next.js, но в процессе работы неприятно удивил целый ряд недостатков и костылей. Пришлось отказаться от Next в пользу свежевышедшего Gatsby.js ver 2.
Первая приятная неожиданность — Gatsby имеет специальный плагин для Drupal, позволяющий легко и непринуждённо подгружать контент через новомодный GraphQL, используя визуальный интерфейс. Никакого шаманизма, обнаженки и ритуальных танцев, всё работает "из коробки".
Кроме удобства разработки, порадовал и процесс деплоя. В качестве хостинга был выбран Netlify. В нём нужно было просто привязать мой репозиторий проекта на Gitlab и вуаля — при каждом коммите он автоматически деплоит на продакшн (опция на любителя, но для моего случая то, что надо).
Статические сайты имеют свои особенности и ограничения, но производительности им не занимать.
Оказывается, один из ключевых разработчиков Gatsby долгое время занимался Drupal-разработкой, отсюда и такая качественная поддержка. Я остался доволен симбиозом этих платформ и могу порекомендовать уважаемому и любимому русскоязычному Drupal-community (которое столько раз мне помогало:)
Всем удачи!
Комментарии
Спасибо за материал!
Небольшой FYI:
- Статические сайты - это совсем про другое, это готовый ХТМЛ, без динамики (пред / пост обработок)
- Headless и Decoupled - тоже не одно и то же Хоть и похожи. Тут можно читнуть.
Ну, и круто было бы о реализации упомянуть. Что использовалось, как и главное - зачем ))
Если честно, то статические сайты - это именно про то, а не другое. Введите в поиск Static site generators, и Gatsby будет среди первых ответов. Выражается это в частности в том, что каждый раз, когда я обновляю контент в Drupal, мне нужно заново сделать gatsby build и задеплоить новую версию.
По поводу decoupled в основном я делаю progressive decouple, где ее компоненты React внедряются как отдельные элементы на страницы, генерируемые Drupal, но в данном случае имеем полный decouple, где друпал выступает просто как сервер для генерации контента.
Я чуть позднее распишу детали.
Сорри, я не особо вникал в тонкости работы Gatsby, и решил что это очередной фреймворк для фронта, а из выдержек:
и
сделал вывод о классическом интерфейсе работы с API, которая исключает статичность.
А что в нексте не так?
Речь идёт не о Next.js в целом, а о применении её в моей конкретной задаче. К сожалению, не запомнил всех моментов, которые меня огорчили (сайт этот делал в свободное время понемногу, и с Next я начал ещё в августе), но кое-что всё же запомнилось. Например, для поддержки самой популярной на сегодня UI-библиотеки для React – Antd потребовались немыслимые костыли, в то время, как в Gatsby достаточно установить плагин .
А поддержки Antd, кстати, нет и по сей день.
Конечно, это не критическая проблема, но неплохо демонстрирует разницу подходов двух обсуждаемых фреймворков к использованию популярных инструментов для разработки.
Вообще, мне показалась близкой и логичной модульная архитектура Gatsby. В активной разработке находятся плагины на все случаи жизни. Вот плагин для Drupal. Всё, что требуется для интеграции Drupal, это установить модуль JSONAPI (последняя версия RC3 глючная, ахтунг!) и в конфиг-файле Gatsby указать URL вашего Drupal-сайта.
При запуске Gatsby автоматически создаёт Schema со структурой вашего контента.
Далее через интерфейс GraphiQL запрашиваем нужные поля (можно изучить сгенерированную Schema через этот же интерфейс, чтобы понять что где находится, а можно написать в левом окне query {} и нажимая shift+space выбирать доступные поля из предложенного dropdown-меню.
Кстати, такую же удобную интеграцию GraphQL имеет и взлетающий на гребне популярности React-apollo.
Можно поподробнее, что нужно сделать после публикации нового контента?
И второй вопрос: так ли хороши styled components? Не увеличивают ли они количество кода за счёт отсутствия каскадностп? И куда в итоге попадают скомпилированные стили?
Большим отличием от обычного приложения React, интегрированного с Drupal, является момент, когда осуществляется fetch. В обычном приложении, как Вы знаете, это происходит при обращении к компоненту или в любой другой, установленный разработчиком момент (нажатие кнопки и т.д.)
В Gatsby это происходит в момент сборки (не важно dev или build)
Т.е. после обновления контента в Drupal я запускаю две команды gatsby build, затем git commit. Поскольку в Netify у меня выбран continuous deployment, и он привязан к моему Gitlab-репозиторию, этого достаточно для того, чтобы продакшн-версия обновилась в течение минуты.
Styled Components мне понравился тем, что в отличие от остальных методов CSS-in-JS он не вводит никаких изменений в синтаксис самого CSS. Просто берётся любой элемент HTML, например,
<div>
и ему присваивается любое разумное название, например,<SectionWrapper>
если он служит обёрткой для секции или просто<StyledWrapper>
Далее прямо в этом же компоненте одноимённой переменной в обратных ковычках (template strings) присваиваются нужные свойства CSS.Для повторяющихся значений существует theming
В отдельном файле создаём переменные, затем используем их где угодно с помощью вот такого синтаксиса:
color: ${(props) => props.theme.colorPrimary};
С media queries тоже всё проще некуда:
При сборке всё это конвертируется в обыкновенный CSS с длинными названиями классов (пример - MyTechComponent__StyledH1-sc-13xb279-1), которые гарантировано не пересекутся с каким-нибудь другим UI-Framework'ом или ранее созданным классом.
Наслышан про генераторы статики, но как по мне, это только усложняет экосистему и процесс публикации. На том же нексте можно было собрать то же самое, только не надо было бы после каждой публикации билдить всё заново.
Про невозможность интеграции антд с некстом не верю.
У всего есть плюсы и минусы. Оф. сайт React тоже сделан на Gatsby.
А по поводу Antd я выше постил ссылку на открытый issue.
Там issue не открытый, а закрытый)) Ну да ладно, не в этом суть. С некстом вообще абсолютно всё интегрируется через боль)))
Но вообще, в последнее время я пришёл к выводу, что decoupled-архитектура хороша только для больших или слишком специфических проектов. Для визиток, корпоративных сайтов и простых интернет-магазинов это всё будет только лишним усложнением.
Согласен, хотя работать в связке Drupal+Gatsby для меня было одно удовольствие (учитывая изначальную простоту проекта).
Случаи, когда decouple действительно полезен довольно ограничены, но они есть. Например, сейчас работаю над большим проектом, в котором Drupal выступает единственным источником контента для целого ряда приложений, в т.ч. использующих React.
Возможно, в данный момент мы находимся в переходном периоде, когда подобные headless связки не совсем оправданы, но если Drupal будет развиваться, как заявлено, нас ждёт весьма интересное время:)
Да это очень интересно. Но потом как посмотришь, сколько времени ушло на проект, то сразу становится всё понятно)))
Кстати, ещё один момент по decoupled: все эти JSON:API и GraphQL по началу кажутся очень крутыми, но потом со временем надоедают, т.к. на фронте постоянно приходится писать сложные запросы и парсить не менее сложные ответы на них. Когда добираешься до subrequests, то начинаешь в панике оглядываться на проекты других людей, смотришь во вкладку Network в девтулзах и постоянно задаёшься вопросом, почему у них красивый json, а у тебя непонятная белиберда с кучей вложенностей и инклюдами, идущими всегда не по месту. И в такой момент начинаешь понимать, что для многих вещей проще и удобнее собрать REST-вьюху, а где-то кастомный рест-эндпоинт сможет убрать головную боль и повысить производительность.
Как бы то ни было, от JSON:API я полностью отказываться не собираюсь, но местами уже стараюсь избегать.
Мне тоже не нравятся эти километровые линки в JSONAPI с фильтрами и инклюдами, которые надо собирать вручную, ковыряясь в документации. В GraphQL это реализовано по-человечески - выбирай из списка полей и копируй готовый сниппет.
К счастью, судя по тенденциям, GraphQL рано или поздно станет стандартом.