Gatsby: трансформеры и плагины

Gatsby использует Remark и Rehype как ядро для обработки Markdown и HTML в процессе построения сайта. Remark отвечает за разбор Markdown в абстрактное синтаксическое дерево (AST), предоставляя возможность модификации структуры контента через плагины. Rehype работает с HTML AST, позволяя выполнять трансформации HTML после конвертации Markdown или для обычного HTML-контента.


Структура AST

Remark AST

Remark разбивает Markdown на узлы, представляющие различные элементы: заголовки, параграфы, списки, изображения, ссылки и т.д. Каждый узел имеет тип (type), свойства (data, value) и дочерние узлы (children). Типичная структура:

{
  type: 'root',
  children: [
    {
      type: 'heading',
      depth: 2,
      children: [{ type: 'text', value: 'Заголовок второго уровня' }]
    },
    {
      type: 'paragraph',
      children: [{ type: 'text', value: 'Текст параграфа' }]
    }
  ]
}

Ключевой особенностью Remark является возможность использования плагинов, которые могут:

  • модифицировать существующие узлы;
  • добавлять новые узлы;
  • извлекать данные из контента для использования на страницах Gatsby.

Rehype AST

После конвертации Markdown в HTML Remark передает результат Rehype. Rehype AST (hast) имеет аналогичную структуру, но ориентирован на HTML-теги:

{
  type: 'element',
  tagName: 'p',
  properties: {},
  children: [
    { type: 'text', value: 'Пример параграфа' }
  ]
}

Плагины Rehype позволяют:

  • добавлять атрибуты к HTML-тегам;
  • вставлять классы и стили;
  • выполнять сложные преобразования HTML-структуры.

Настройка Remark и Rehype в Gatsby

В gatsby-config.js подключение выглядит следующим образом:

module.exports = {
  plugins: [
    {
      resolve: 'gatsby-transformer-remark',
      options: {
        plugins: [
          'gatsby-remark-prismjs',      // подсветка синтаксиса
          'gatsby-remark-images',       // обработка изображений
          {
            resolve: 'gatsby-remark-autolink-headers',
            options: { offsetY: 80 }
          }
        ],
      },
    },
    {
      resolve: 'gatsby-plugin-mdx',
      options: {
        rehypePlugins: [
          require('rehype-slug'),      // добавление id к заголовкам
          require('rehype-autolink-headings')
        ]
      }
    }
  ]
}
  • gatsby-transformer-remark используется для Markdown-файлов, преобразует их в HTML через Remark и Rehype.
  • gatsby-plugin-mdx расширяет возможности Remark для поддержки JSX внутри Markdown и применяет Rehype-плагины для модификации HTML.

Применение трансформеров

Трансформеры — это плагины, которые изменяют AST. Для Remark можно создать собственный плагин:

module.exports = ({ markdownAST }) => {
  const visit = require('unist-util-visit');

  visit(markdownAST, 'text', node => {
    if (node.value.includes('Gatsby')) {
      node.value = node.value.replace(/Gatsby/g, 'GatsbyJS');
    }
  });

  return markdownAST;
};

В этом примере:

  • используется unist-util-visit для обхода всех текстовых узлов;
  • происходит замена ключевого слова на новое значение;
  • модифицированное AST возвращается обратно для дальнейшей обработки Rehype.

Для Rehype процесс аналогичен, но обход происходит по HTML-узлам:

module.exports = () => tree => {
  const visit = require('unist-util-visit');

  visit(tree, 'element', node => {
    if (node.tagName === 'img') {
      node.properties.loading = 'lazy';
    }
  });
};

Здесь все изображения получают атрибут loading="lazy" для оптимизации загрузки.


Ключевые плагины и их применение

  • gatsby-remark-images — конвертирует изображения Markdown в оптимизированные Gatsby Image с поддержкой srcSet и lazy loading.
  • gatsby-remark-prismjs — подсветка кода с настройкой тем и стилей.
  • gatsby-remark-autolink-headers — автоматически добавляет якоря к заголовкам для создания ссылок на разделы.
  • rehype-slug — добавляет id для каждого заголовка в HTML.
  • rehype-autolink-headings — автоматически превращает заголовки в кликабельные ссылки на них.

Тонкости работы с Gatsby и AST

  • Плагины Remark выполняются до конвертации в HTML, что позволяет работать с Markdown на структурном уровне.
  • Плагины Rehype выполняются после конвертации, что делает их идеальными для работы с финальным HTML и добавления атрибутов или классов.
  • Оба вида плагинов можно комбинировать для создания сложных преобразований: например, сначала модифицировать текст Markdown, затем добавить стили и атрибуты к HTML.

Практическая схема потока данных

  1. Markdown-файл → gatsby-transformer-remark
  2. Remark-плагины → модификация AST Markdown
  3. Конвертация AST Markdown → AST HTML (Rehype)
  4. Rehype-плагины → модификация HTML AST
  5. HTML встраивается в страницы Gatsby

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


Использование кастомных плагинов в MDX

MDX объединяет возможности Markdown и JSX. Применение Rehype-плагинов позволяет модифицировать HTML, созданный из JSX или Markdown:

const rehypePlugin = require('./rehype-custom-plugin');

export const components = {
  wrapper: ({ children }) => 
{children}
}; export const rehypePlugins = [rehypePlugin];

Такой подход позволяет создавать сложные страницы, где контент полностью контролируется через AST и преобразования Remark/Rehype.