Что нового и что такое Nuxt

Ждали, когда Nuxt 3.0 создаст Jamstack (статические) приложения? В этом нет нужды. Последняя версия Nuxt, v2.14, может быть именно тем, что вы ищете.

Любопытный? Давайте начнем.

Что такое Jamstack?

Для тех, кто не был знаком, Jamstack (или JAMstack) - это архитектура веб-разработки, в которой JAM означает клиентский JavaScript, многоразовые API-интерфейсы (вместо нескольких веб-серверов) и предварительно созданные разметки (статические файлы HTML).

Jamstack стремится предоставлять более быстрые, масштабируемые и более защищенные приложения, создавая их как статические. Тенденция Jamstack начинается в 2019 году, и мы ожидаем, что она сохранит свою популярность в 2020 году.

Так как же Nuxt - фреймворк Vue на стороне сервера (SSR) - в настоящее время работает с Jamstack?

Давайте разберемся.

Статус Nuxt для Jamstack (до версии 2.13)

Nuxt - супер-крутой фреймворк. Он предлагает две следующие сборки mode для единой кодовой базы:

  • universal SSR (рендеринг на стороне сервера)
  • spa одностраничное приложение

Позже, для поддержки Jamstack, команда Nuxt предлагает дополнительную команду сборки nuxt generate, которая действует как генератор статических сайтов (SSG).

Тем не менее, его механизм генератора статических сайтов не совсем ожидаемо для стандартного генератора статических сайтов (SSG) с некоторыми следующими ограничениями:

  • В отличие от обычных SSG, где все данные для страницы предварительно выбираются во время сборки, ядро ​​Nuxt предварительно визуализирует шаблоны и содержимое во время сборки, но извлекает внешние данные во время выполнения, используя fetch и asyncData. Таким образом, сгенерированные страницы являются только наполовину статичными. Кроме того, полагаясь на внешние вызовы для завершения выборки и рендеринга данных на стороне клиента, могут возникать задержки в отображении контента пользователю, что влияет на общую производительность приложения.
  • Поскольку Nuxt не имеет встроенного уровня данных, такого как GraphQL, движок Nuxt не знает, как автоматически генерировать все динамические маршруты для содержимого из внешней базы данных. Разработчики должны указать, как создавать эти маршруты, используя свойство generate.routes в файле nuxt.config.js. Эта дополнительная работа приводит к сложности и возможному замедлению времени сборки, что приводит к экономической эффективности, особенно когда большинство хостинговых услуг, таких как Netlify, взимают плату за время сборки.
  • Встроенной поддержки Markdown нет. Мы можем использовать модуль @nuxtjs/markdownit; однако разработчикам сложно выполнить дополнительную настройку этого модуля.

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

Но с Nuxt 2.13 и новее и Nuxt Content Module эти ограничения наконец-то исчезли.

Полный статический запуск из процесса сборки

Для удобства разработчиков, начиная с версии 2.13, Nuxt вводит новое свойство target: static, в то время как mode остается universal (по умолчанию) или spa в nuxt.config.js, чтобы информировать движок Nuxt. Наше приложение должно быть полностью статичным.

/* nuxt.config.js */
export default {
 mode: 'universal', // default mode
 target: 'static', // enable full static mode
 //...
}

Оптимизируйте сборку с помощью nuxt generate

До Nuxt v2.13 для создания проекта кода как статического мы использовали nuxt generate. Вызывая nuxt generate, механизм Nuxt фактически запускает nuxt build процесс сборки, а затем экспортирует страницы приложения в статические HTML-файлы перед развертыванием.

Начиная с версии 2.14, nuxt generate умнее. Он определяет отсутствие изменений кода и пропускает этап сборки. Вместо этого он повторно использует кеш предыдущей сборки и продолжает генерировать статические HTML-файлы.

Кроме того, механизм Nuxt умеет обнаруживать и отделять любой дополнительный вызов асинхронного API на стороне клиента (по asyncData или fetch) от сгенерированных HTML-страниц в .js файл (ы) полезной нагрузки соответственно. Следовательно, это значительно уменьшает размер сгенерированных HTML-страниц, обслуживаемых. Одновременно во время выполнения файлы полезной нагрузки будут предварительно загружены, что позволит оптимизировать производительность приложения и исключить дополнительные вызовы API при навигации на стороне клиента.

Отлично, не правда ли? Следующий вопрос: зачем нам хранить кеш для создания статических приложений?

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

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

Вы упоминаете динамический маршрут, Nuxt автоматически сканирует его

Начиная с версии 2.13, Nuxt предлагает нечто более мощное, чем необходимость в одном уровне данных и generate.routes. Пока вы упоминаете свой динамический маршрут на любой странице (например, список сообщений в блоге на главной странице), поисковый робот Nuxt обнаружит и убедится, что все упомянутые маршруты предварительно сгенерированы во время сборки и развертывания.

По умолчанию поисковый робот Nuxt включен автоматически. Тем не менее, если мы хотим использовать нашу логику для генерации маршрутов, мы можем отключить ее, установив crawler: false и продолжить реализацию export.routes в nuxt.config.js.

Круто, не правда ли? И это еще не все. Nuxt v2.14 превосходен, а с его модулем содержимого Nuxt его статическая мощность еще выше.

Давай проверим контент Nuxt, ладно?

Вы пишете контент, Nuxt позаботится о рендеринге

Модуль содержимого Nuxt, @nuxt/content, - это новый модуль, разработанный Бенджамином Канаком из команды Nuxt. На момент написания этого поста выпуск Nuxt Content имел версию 1.4.1.

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

Чтобы начать использовать Nuxt Content, выполните одну из следующих команд:

yarn add @nuxt/content

#OR
npm i @nuxt/content

Затем добавьте модуль в список modules в nuxt.config.js:

modules: [
 '@nuxt/content'
]

И модуль готов к использованию.

Простой способ использования

По умолчанию движок Nuxt будет использовать content/ часть в качестве основного каталога для всех файлов Markdown.

Модуль содержимого глобально внедряет экземпляр функции the$content в наше приложение, поэтому мы можем использовать его для прямого извлечения содержимого по заданному пути. Например, мы можем получить список сообщений блога из каталога content/blog, как показано ниже:

Этот $content экземпляр получает два аргумента: path и дополнительный объект options, который обеспечивает дополнительную конфигурацию для модуля, чтобы переопределить настройки по умолчанию для данного пути. Например, нам нужно только разрешить deep: true получать файлы из подкаталогов, как в следующем коде:

Или, чтобы получить один файл, мы можем передать имя файла в аргумент path или напрямую как options:

Оба подхода законны. $content() возвращает цепочку типа QueryBuilder. Затем мы можем вызвать его метод fetch(), чтобы начать получение содержимого с помощью Promise.

Когда fetch() разрешается, он возвращает либо объект (если path - это единственный путь к файлу), либо массив объектов (если path - это каталог). Каждый объект имеет структуру, аналогичную приведенной на снимке экрана ниже, с автоматически созданными свойствами, такими как body (основное содержимое), createdAt, dir, extension, path, slug (имя файла), toc (оглавление) и updatedAt.

Когда у нас есть объект возвращаемого содержимого, мы можем просто использовать компонент nuxt-content в разделе шаблона для отображения тела содержимого:

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

Как видно на снимке экрана, Nuxt Content отображает контент только с самыми простыми стилями (т.е. без стиля), чтобы не создавать сложности при применении настройки стиля CSS. Nuxt предоставляет нам селектор классов .nuxt-content для компонента <nuxt-content>, и мы можем начать настраивать стили оттуда, например:

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

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

  1. Получите контент с помощью $content().fetch().
  2. Визуализируйте полученный контент, используя <nuxt-content> и его свойство document соответственно.
  3. Добавьте стили CSS к отображаемому контенту с помощью селектора классов .nuxt-content.

Большой? Действительно. Есть ли какие-нибудь другие уникальные функции, которые предлагает Nuxt Content, кроме?

Поиск и фильтрация результатов контента

Поскольку Nuxt Content использует синтаксис запросов, подобный LokiJS и MongoDB, мы можем добиться высокой производительности при поиске и фильтрации определенного набора результатов контента с помощью последовательной цепочки методов. Например, если мы хотим выбрать только свойства title, slug и updatedAt каждого объекта содержимого и отсортировать сообщения по времени редактирования (в порядке убывания), мы можем сделать это следующим образом:

Здесь only получает массив ключей для выбора из каждого возвращенного объекта содержимого, а sortBy принимает два аргумента: ключ для сортировки и направление сортировки.

Вы также можете фильтровать сообщения, соответствующие определенным условиям, используя where, например:

Или вы можете выполнить полнотекстовый поиск в поле с search(key, value):

Кроме того, вы можете реализовать разбиение на страницы, ограничив результаты, получаемые limit():

Вы можете изучить другие полезные методы связывания в документации Nuxt Content и LokiJS, чтобы узнать о синтаксисе запросов, поддерживаемом этими методами.

Примечание. Вся цепочка последовательностей должна заканчиваться fetch() для сбора необходимых данных через Promise API.

Подсветка кода с помощью PrismJS

Nuxt Content использует PrismJS в качестве встроенного обработчика для выделения кода в содержимом Markdown. Тема по умолчанию довольно приличная; однако мы всегда можем установить prism-themes и выбрать другую тему из списка доступных тем (24 различных темы) для использования в нашем приложении:

yarn add prism-themes

Затем определите желаемую тему в поле content.markdown.prism в nuxt.config.js, как показано в примере ниже:

И ваш визуализированный контент с выделением кода будет выглядеть так:

Красиво, не правда ли? Нет более сложного обходного пути для поддержки выделения кода для Markdown. Кроме того, вы всегда можете создать свою собственную тему, поскольку репозиторий prism-themes имеет открытый исходный код.

YAML внутри Markdown

Одной из приятных особенностей Nuxt Content является возможность поддержки основного блока YAML в файле Markdown, если он отображается вверху и принимает правильную форму YAML, установленную между линиями, пунктирными тройками:

--- 
title: Hello World description: Hello to Nuxt content demo img: nuxt_demo/DSC00856 
author: Maya Shavin 
---

Модуль содержимого Nuxt вставит эти поля в качестве свойств в объект содержимого, переданный document компонента nuxt-content, как показано в примере ниже:

Запись блока YAML внутри файла Markdown позволяет нам легко добавлять дополнительную настраиваемую информацию, такую ​​как данные об авторе, для сообщения в блоге.

Автоматическое создание оглавления

При получении файла Markdown содержимое Nuxt автоматически создает таблицу содержимого (TOC), которая состоит из всех заголовков внутри файла. TOC представляет собой массив и появляется как свойство возвращаемого объекта содержимого. Каждый элемент массива toc представляет собой объект с тремя основными полями:

  • id - название заголовка в нижнем регистре и без пробелов, для ссылки
  • depth - тип заголовка (1 = h1, 2 = h2 и т. Д.)
  • text - собственно текст заголовка заголовка

Вот пример файла Markdown со следующим содержанием:

# Hello World

## Hello Heading 1

Lorem ipsum dolor sit amet

Содержание Nuxt будет генерировать содержание следующего содержания:

И из этой структуры оглавления мы можем соответствующим образом построить и отобразить наш компонент оглавления.

Потрясающие. Что еще?

Все дело в крючках!

В настоящее время Nuxt Content предлагает два основных крючка:

  • content:file:beforeInsert позволяет добавлять в документ дополнительные данные перед его сохранением для рендеринга. Например, полезно добавить внешнюю логику, такую ​​как расчет времени чтения для времени сборки, тем самым оптимизируя производительность на стороне клиента.
  • content:update при обновлении файла содержимого. Этот хук полезен, когда вы хотите реализовать горячую перезагрузку или редактирование в реальном времени.

Мы можем добавить желаемые перехватчики, используя свойства hooks в nuxt.config.js, как в следующем примере:

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

Круто, не правда ли? С помощью этих функций мы можем создать полностью статический сайт, блог или интернет-магазин, используя только файлы Markdown и Nuxt.

Действительно, это не единственные функции, которые может предложить Nuxt Content. А создание производительного и красивого статического сайта требует сочетания эффективных инструментов, ядром которых является Nuxt и Nuxt Content.

Демо

Для экспериментов я сделал демо-версию PWA для туристической компании, используя Nuxt, Nuxt Content, TailwindCSS, Cloudinary, и развернул ее автоматически с помощью Netlify.

Вы можете проверить приложение здесь: https://tfh-tours.netlify.app/

А исходный код, как всегда, открыт и доступен в этом репо: https://github.com/mayashavin/tours-nuxt-full-static

Заключение

Nuxt v2.1x и Nuxt Content, на мой взгляд, замечательные релизы от команды Nuxt. Помимо упомянутых улучшений сборки для статических сайтов, новый Nuxt также предоставляет другие функции, которые призваны сделать жизнь разработчика более комфортной, например компоненты для автоматического обнаружения, настройки времени выполнения, телеметрии и поддержки тем.

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

Если вы дойдете до этой черты (я ценю это), почему бы не попробовать Nuxt (если вы этого не сделали) и посмотреть, как он расширяет возможности вашего следующего проекта Jamstack?