Последние несколько месяцев мы потратили на создание новой версии нашей корзины.

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

Документация была одним из них.

Это означало несколько конкретных и столь необходимых обновлений:

  • Улучшение навигации между версиями документов
  • Переосмысление древовидности контента
  • Максимально автоматизируйте создание документации

Мы также хотели оставаться верными тому, что проповедуем; используя JAMstack! Это означало выбор правильных инструментов JavaScript для создания нашей документации.

В итоге мы выбрали Nuxt для создания статической документации, Sanity.io для управления контентом и Netlify для автоматического развертывания. Я объясню, почему позже.

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

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

Отказ от ответственности: имейте в виду, что это текущая бета версии 3.0 только для целей разработки и тестирования.

Наша генерация документации (немного контекста)

Наш старый документ был создан с использованием пользовательского Node.js и требовал рендеринга на стороне сервера при каждой загрузке новой страницы. Мы часто забывали документировать новые исправления и простые функции. Были также досадные ошибки и опечатки время от времени. Короче говоря, документация часто может стать занозой в заднице. Я уверен, что некоторые из вас могут относиться к этому.

Итак, для нашей новой документации мы поставили перед собой несколько целей. Это должно было:

  • Быть развернутым как полностью статический сайт
  • Размещайтесь на быстром CDN
  • Используйте Vue.js во внешнем интерфейсе (поскольку это основной фреймворк нашей команды).
  • Упростите редактирование контента для всей команды, а не только для разработчиков!
  • Убедитесь, что все методы нашего Javascript API и переопределяемые компоненты темы правильно задокументированы.

Эта комбинация критериев привела к очевидному выбору стека: генератор статических сайтов на базе Vue, подключенный к безголовой CMS.

Как поклонники автоматизации, мы не хотели самостоятельно управлять документацией компонентов нашей темы и Javascript API. Данные документации необходимо будет сгенерировать во время сборки из кода и комментариев JSDoc.

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

Это также добавило ограничение выбора безголовой CMS с мощным API для обновления контента.

Почему Sanity как безголовая CMS?

Есть много-много безголовых CMS. Я предлагаю провести тщательное исследование и взвесить все за и против, прежде чем сделать выбор. В нашем случае есть несколько критериев, которые сделали баланс в пользу Sanity.io:

  • Отличный готовый опыт редактирования
  • Полностью размещен - нет необходимости управлять этим в нашей инфраструктуре
  • Открытый исходный код и настраиваемый
  • Отличный API как для запросов, так и для записи
  • Веб-хуки, позволяющие нам перестраивать документ после редактирования контента.

Начать проект Sanity очень просто. Во вновь созданном репо запустите sanity init.

Затем определите несколько типов документов и, если вам так хочется, создайте несколько пользовательских компонентов, чтобы адаптировать редактирование к вашим конкретным потребностям. Даже если вы приступите к настройке, это не помешает вам развернуть вашу CMS на Sanity — вот где она действительно сияет, потому что высокая настраиваемость — довольно редкая черта в размещенных решениях.

API Sanity также стал глотком свежего воздуха.

GROQ, их язык запросов, является долгожданным дополнением к экосистеме. Подумайте о GraphQL, не требуя всегда явно указывать все поля, которые вы хотите в запросе (или иметь возможность запрашивать полиморфные данные, не чувствуя себя подвигами Геракла).

Кроме того, изменения могут быть ограничены транзакцией, что позволяет нам пакетно обновлять несколько документов из нашей темы и процесса сборки SDK. Объедините это с веб-хуками, и это гарантирует, что мы инициируем развертывание документации только один раз для многих изменений из нашей темы и репозиториев SDK.

Почему Nuxt как генератор статических сайтов?

Как только вы подумали, что есть из чего выбрать безголовые CMS, вы наткнулись на десятки существующих SSG.

Основными требованиями к нашему генератору статических сайтов были:

  • Развертывает только статические файлы
  • Использует Vue.js
  • Извлекает данные из внешнего API

Использование Vue.js здесь может показаться произвольным, и вы будете правы, спросив: «Почему бы не реагировать или что-то еще?» Справедливости ради, поначалу это было немного произвольно, поскольку это сводится к личным предпочтениям команды, но по мере того, как мы создаем все больше и больше проектов, мы также ценим согласованность во всех них.

Мы долгое время использовали Vue.js в панели инструментов, и мы сделали все возможное для нашей темы по умолчанию v3.0. В конце концов, эта согласованность позволит нам не только быстрее интегрировать членов команды, но и повторно использовать код. Допустим, мы хотели бы создать предварительный просмотр настройки темы в реальном времени; совместное использование одного и того же стека между документами и темой упрощает эту задачу.

При этом у нас осталось три претендента на SSG: VuePress, Nuxt и Gridsome.

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

→ Nuxt.js. Это мощное средство разработки SPA с помощью Vue. Он предлагает отличную структуру и только правильные точки расширения, чтобы быть по-настоящему гибким. Команда nuxt generate позволяет развернуть полностью статическую и предварительно обработанную версию веб-сайта. Однако создание веб-сайта, ориентированного на контент, вместо динамического веб-приложения требует дополнительной работы.

→ Загадочный. Вдохновленный Гэтсби, он имеет первоклассную поддержку внешних источников данных и был создан для создания статических веб-сайтов на основе этих данных. Уже поэкспериментировав с ним и потому что он поставил все галочки, Гридсом сначала казался избранным.

Однако мы быстро наткнулись на некоторые болевые точки:

  • Автоматическое создание схемы GraphQL имеет некоторые проблемы и часто требует указания типа полей вручную.
  • Мы не могли структурировать наши данные так, как хотели. Нам нужно было хранить function, class и enum, и все они должны были быть полиморфно связаны со страницами документации.
  • Давайте будем честными, необходимость иметь дело со схемой GraphQL просто замедляет циклы итераций.

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

В конце концов, мы решили использовать Nuxt и доработать недостающие части вручную.

С Gridsome 0.7 вы можете указать типы схемы GraphQL и поставляется с плагином источника данных Sanity.

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

Наше новое поколение документации в стиле Javascript

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

Хотя некоторые отдельные части относительно сложны, собрать их вместе было довольно легко.

Наша документация состоит из традиционных страниц с контентом, написанных нашей командой разработчиков или маркетологов, и технического контента, извлеченного из двух репозиториев:

Страницы контента редактируются непосредственно в Sanity CMS. Что касается технического контента, он генерируется автоматически с использованием API компилятора Typescript и передается в API Sanity в скрипте нашего CI при обновлении каждого репо. Этот скрипт использует функцию транзакций Sanity для одновременного обновления всех модификаций.

Изменения в Sanity генерируют веб-хук, который мы используем для запуска сборки на Netlify. Обработка веб-перехватчиков в настройке JAMstack часто требует использования какой-то лямбда-функции в качестве логического слоя между исходным веб-перехватчиком и целевым API.

Однако здесь мы можем воспользоваться умным предвидением Netlify. Их входящая конечная точка веб-перехватчика — это простой частный URL-адрес, который принимает любой запрос POST для запуска сборки, а это означает, что веб-перехватчик Sanity может быть настроен непосредственно на него!

Как только сборка запущена, она запускается nuxt generate. Наш пользовательский код извлекает данные из Sanity, и папка dist развертывается на молниеносно быстрой CDN.

Короче говоря, Sanity используется как хранилище всего необходимого в наших документах. Сама документация всегда актуальна для всего, что выпускается в производстве. Документация, поступающая из источников, может быть проверена в рамках регулярного процесса проверки кода.

Генерация документации из исходников

Все наши проекты версии 3.0 находятся в Typescript, что позволяет нам использовать его API-интерфейс компилятора для извлечения документации из исходного кода. Это происходит в три этапа:

  1. Компилятор автоматически генерирует определения типов (файл .d.ts) проекта, исключая все типы, помеченные как внутренние (используя теги @internal в комментариях JSDoc). Это достигается простой установкой declaration и stripInternal в true в нашем tsconfig.json
  2. Наш пользовательский скрипт выполняется; он читает файл .d.ts, анализирует его с помощью API компилятора и передает результат в библиотеку под названием readts, которая преобразует вывод компилятора в более управляемую структуру данных.
  3. Наконец, наш скрипт обновляет базу данных Sanity, используя их модуль npm.

Возьмем эту функцию в качестве примера:

Он экспортируется в объявление типа нашего SDK почти как есть, за исключением тела метода. Следующий код позволяет нам преобразовать read it структурированным образом:

После загрузки в набор данных Sanity предыдущее объявление функции выглядит следующим образом:

Использование readts может выглядеть как прогулка в парке, но использование API-интерфейса компилятора Typescript не для слабонервных. Вам часто придется погружаться в символы компилятора (не путать с символами из языка), узлы AST и их SyntaxKind значений перечисления.

Теперь данные готовы к использованию нашей SSG, давайте посмотрим, как мы подключили Nuxt!

Делаем Nuxt полностью статичным и управляемым контентом

С помощью команды nuxt generate Nuxt.js может генерировать полностью статический веб-сайт во время сборки.

Однако, в отличие от Gatsby или Gridsome, которые кэшируют узлы контента, выборка данных по-прежнему выполняется даже в статическом режиме с Nuxt. Это происходит из-за того, что метод asyncData вызывается всегда, и разработчик должен предоставить отдельную логику, если это необходимо. В сообществе Nuxt уже есть разговоры об исправлении этого. Но нам это было нужно СЕЙЧАС 🙂

Мы подошли к этой проблеме с помощью модуля Nuxt, который по-разному ведет себя при вызове с клиента (статический веб-сайт) или с сервера (при вызове nuxt generate). Этот модуль объявляется в нашем nuxt.config.js:

Затем он просто регистрирует сервер и клиентский плагин:

Они оба предоставляют один и тот же метод для каждого компонента страницы для загрузки данных. Отличие заключается в том, что на сервере этот метод напрямую вызывает Nuxt API для получения контента:

На клиенте плагин вместо этого загрузит статический файл JSON:

Теперь в компоненте нашей страницы мы можем вслепую вызвать loadPageData, и модуль и плагины гарантируют, что используется правильная версия:

Вот краткий обзор того, как функция, о которой я говорил ранее, выглядит в документе:

Окончательный результат:

Вы можете посетить документы здесь.

Хотите протестировать нашу бета-версию v3.0? Вот вся информация.

Заключительные мысли

Начать работу с Sanity было очень просто, и, хотя мы еще не продвинулись далеко, все выглядит специально созданным для плавного расширения. Я был действительно впечатлен их API, запросами с помощью GROQ и тем, как можно создавать плагины для CMS.

Что касается Nuxt, хотя для нашего варианта использования он потребовал больше работы, он по-прежнему обеспечивает прочную основу для создания любого проекта Vue.js.

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

Есть вопросы? Не стесняйтесь нажимать комментарии, чтобы поделиться с нами своими мыслями, отзывами и вопросами. Если вам понравился этот пост, уделите секунду 👏 или поделитесь им в Твиттере!

Первоначально опубликовано в блоге Snipcart и в нашей рассылке.