Основы работы с плагином MDX в Gatsby

Если вы ранее использовали файлы Markdown в своих проектах Gatsby.js, вы уже знаете, что это потрясающий способ создания контента. Но простой Markdown ориентирован на текстовый контент, и его возможностей может оказаться недостаточно, если вы захотите выйти за эти рамки. К счастью, для таких случаев существует MDX, расширенный набор Markdown, который позволяет встраивать JSX непосредственно в файлы Markdown. Звучит круто, не так ли? В этой статье мы рассмотрим основы работы MDX в Gatsby, в том числе изучим некоторые вводные методы, которые помогут вам начать использовать его прямо сейчас.

Прежде чем приступить к работе, убедитесь, что у вас есть проект Gatsby, настроенный и готовый к редактированию. Если вам нужна помощь в создании такого проекта, читайте мануал Gatsby v2: с чего начать работу?.

Установка MDX

Благодаря невероятной библиотеке плагинов Gatsby процесс установки очень прост. Для использования MDX требуется только один плагин, gatsby-plugin-mdx, а также одноранговые зависимости MDX.

Давайте установим их. Это делается вот так:

$ yarn add gatsby-plugin-mdx @mdx-js/mdx @mdx-js/react

Давайте также установим gatsby-source-filesystem, чтобы получить возможность использовать frontmatter, генерировать ноды Gatsby из локальных файлов и использовать функции импорта/экспорта в файлах MDX:

$ yarn add gatsby-source-filesystem

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

Конфигурация MDX

Как и в случае с другими плагинами Gatsby, после установки нам нужно добавить детали конфигурации в раздел plugins в файл gatsby-config.js.

Давайте настроим gatsby-plugin-mdx и gatsby-source-filesystem следующим образом:

module.exports = {
  //...siteMetadata, etc
  plugins: [
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `pages`,
        path: `${__dirname}/src/pages/`,
      },
    },
    {
      resolve: `gatsby-plugin-mdx`,
      options: {
        defaultLayouts: {
          default: require.resolve(`./src/components/layout.js`),
      },
    },
    // ... other plugins
  ],
}

Обратите внимание, что мы устанавливаем ключ default в опции defaultLayouts. Это автоматически завернет все файлы MDX стандартным компонентом layout.js нашего сайта.

Примечание: Файл gatsby-config.js был отредактирован, поэтому не забудьте перезапустить среду разработки, прежде чем продолжить.

Доступные конфигурации

Для gatsby-plugin-mdx доступно несколько вариантов конфигурации:

  • extensions: это массив строк, определяющий расширения файлов, которые будут обрабатываться как MDX. Часто здесь устанавливается значение [‘.mdx’, ‘.md’], чтобы также обрабатывать обычные файлы Markdown как MDX.
  • defaultLayouts: объект. Обычно используется, когда у вас есть несколько типов генерируемого контента, например посты в блогах и обзоры продуктов. И, как показано выше, вы также можете установить ключ default и автоматически обернуть все файлы MDX.
  • gatsbyRemarkPlugins: массив объектов плагинов. Это позволяет нам использовать различные плагины Gatsby вместе с обработкой выражений MDX. Здесь часто используется плагин gatsby-remark-images.
  • commentPlugins: массив объектов плагинов. Работает аналогично приведенному выше параметру, но предназначен для плагинов примечаний, не зависящих от Gatsby.
  • rehypePlugins: массив объектов плагинов. Аналог предыдущих параметров, но предназначен для плагинов rehype.
  • mediaTypes: массив строк. Он устанавливает, какие типы мультимедиа обрабатываются. Вероятно, вам не придется использовать его очень часто.

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

Основы работы с MDX

Конфигурация, которая у нас есть на данный момент, уже может обрабатывать все файлы .mdx на нашем сайте. Благодаря стандартному поведению Gatsby, если мы добавим эти файлы в каталог src/pages/, они автоматически станут страницами.

Давайте сделаем это сейчас, создав простой файл MDX по имени src/pages/mdx-intro/index.mdx. Начнем с простых вводных и основного текста Markdown, как будто это типичная страница блога Markdown:

---
title: MDX is Magical!
path: /mdx-intro
date: 2019-08-25
---


# Hooray For MDX!

This will be like turbo-charged Markdown!

Вы можете просмотреть эту новую страницу, посетив http://localhost:8000/mdx-intro в своем браузере.

Вы, вероятно, узнаете этот шаблон, если ознакомились с мануалом Gatsby v2: с чего начать работу?, Разница лишь в том, что это файл MDX, а не Markdown, но пока в этом нет ничего особенного или нового. Давайте изменим это!

Компоненты MDX

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

Чтобы посмотреть, как это работает, давайте создадим простой компонент /src/components/TitleBar.js, что позволит нам кастомизировать строку заголовка.

import React from 'react';

const TitleBar = ({ text, size, bkgdColor }) => (
  <div
    style={{
      margin: '2rem 0',
      padding: '2rem',
      backgroundColor: bkgdColor || '#fff',
    }}
  >
    <h2
      style={{
        fontSize: size || '18px',
        margin: 0,
      }}
    >
      {text}
    </h2>
  </div>
);

export default TitleBar;

Теперь давайте обновим наш файл MDX:

---
title: MDX is Magical!
path: /mdx-intro
date: 2019-08-25
---
import TitleBar from "../../components/TitleBar.js";

<TitleBar
  size={"32px"}
  bkgdColor={"#4aae9b"}
  text={props.pageContext.frontmatter.title}
/>

This will be like turbo-charged Markdown!

Здесь следует отметить две вещи:

  • Во-первых, мы только что импортировали и использовали компонент React непосредственно внутри Markdown. Это очень мощная возможность: только представьте себе записи с анимированными диаграммами и динамически загружаемыми данными, сложной интерактивностью и т.д.
  • Во-вторых, как вы могли заметить, мы можем получить доступ к значениям frontmatter из props.pageContext.frontmatter. Это тоже может быть очень полезно.

Примечание: Если ваши MDX-файлы содержат frontmatter, всегда размещайте операторы импорта после блока frontmatter.

Идем дальше. Просмотрите обновленную страницу в своем браузере и попробуйте отредактировать свойства size и bkgdColor, чтобы увидеть, как она обновляется. Это очень простой пример, но опять же: мы используем компонент React внутри Markdown! Довольно круто, правда?

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

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

Настройка макетов по умолчанию

Мы можем настроить стандартные макеты для наших файлов MDX в файле gatsby-config.js (даже для определенных расположений). Взгляните на этот пример gatsby-config.js:

module.exports = {
  plugins: [
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `pages`,
        path: `${__dirname}/src/pages/`,
      },
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `posts`,
        path: `${__dirname}/src/blog/`,
      },
    },
    {
      resolve: `gatsby-plugin-mdx`,
      options: {
        defaultLayouts: {
          posts: require.resolve("./src/components/blog-layout.js"),
          default: require.resolve("./src/components/layout.js"),
        },
      },
    },
  ],
}

В этом примере мы настроили наш сайт таким образом, чтобы все файлы MDX, полученные из каталога /src/blog, использовали blog-layout.js в качестве макета/оболочки. Кроме того, мы настроили параметр default.

Примечание: В настоящее время это поведение не работает должным образом с файлами MDX из каталога pages. Однако вы все равно можете обернуть их в default, как мы это сделали сейчас.

Присваивание и удаление макетов вручную

В некоторых ситуациях нужно обернуть определенный файл MDX в уникальный макет или оставить его вообще без макета. Это можно легко сделать с помощью стандартного синтаксиса экспорта JavaScript внутри файлов MDX, который переопределяет любые настройки defaultLayout. Мы подробно рассмотрим это в следующем разделе.

Импорт других файлов MDX

Помимо импорта и использования компонентов JSX, мы также можем импортировать и использовать другие файлы MDX так, как если бы они были компонентами (ведь по сути они действительно являются компонентами).

Давайте создадим в каталоге компонентов новый файл MDX, /src/components/postSignature.mdx. Мы будем использовать его контент в нижней части страницы MDX в качестве подписи автора.

##### Thanks for Reading!

*🐊 Al E. Gator | alligator.io | al@example.com*

export default ({ children }) => (
  <>
    {children}
  </>
)

Обратите внимание на оператор export default в нижней части файла. Как упоминалось в предыдущем разделе, именно так мы можем переопределить настройки defaultLayout. В данном случае вместо этого мы экспортируем пустую оболочку <> вокруг подписи.

Двигаемся дальше. Давайте импортируем эту подпись MDX в основной файл MDX, /src/pages/mdx-intro/index.mdx:

---
title: MDX is Magical!
path: /mdx-intro
date: 2019-08-25
---
import TitleBar from "../../components/TitleBar.js";
import PostSignature from "../../components/postSignature.mdx";

TitleBar
  size={"32px"}
  bkgdColor={"#4aae9b"}
  text={props.pageContext.frontmatter.title}
/>

This is like turbo-charged Markdown!

<PostSignature />

Теперь вы должны увидеть эту подпись внизу страницы mdx-intro.

GraphQL-запросы

Благодаря сочетанию плагинов gatsby-plugin-mdx и gatsby-source-filesystem мы можем легко получить доступ к страницам MDX через запросы GraphQL.

Мы не будем тратить на это много времени, так как эта функциональность почти идентична запросу простых файлов Markdown. Единственное отличие состоит в том, что ноды MDX находятся в allMdx и mdx, а не в allMarkdownRemark и markdownRemark.

Посмотрите на следующий пример запроса, который извлекает frontmatter всех доступных файлов MDX.

query {
  allMdx {
    edges {
      node {
        frontmatter {
          title
          path
          date(formatString: "MMMM DD, YYYY")
        }
      }
    }
  }
}

Предоставление других данных

Также через файлы MDX мы можем предоставить дополнительные данные, используя синтаксис export JavaScript (не путать с export default). Любые экспортированные переменные автоматически добавляются в схему GraphQL, чтобы при необходимости вы могли использовать их в запросах GraphQL и/или во время рендеринга.

Вот несколько примеров данных «Обзор продовольственных грузовиков», которые мы могли бы добавить на нашу страницу многомерных выражений:

export const myReviews = [
  {
    name: "Tim's Tacos",
    overall: 9,
    variety: 7,
    price: 8,
    taste: 9
  },
  {
    name: "Noodleville",
    overall: 7,
    variety: 5,
    price: 6,
    taste: 8
  },
  {
    name: "Waffle Shack",
    overall: 6,
    variety: 5,
    price: 4,
    taste: 6
  },
];

Добавив такой код в любое место файла, мы можем запросить данные в GraphQL, обратившись к allMdx.nodes.exports, например так:

query MdxExports {
  allMdx {
    nodes {
      exports {
        myReviews {
          name
          overall
          variety
          price
          taste
        }
      }
    }
  }
}

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

Практический пример

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

Для начала добавим на наш сайт библиотеку Recharts. Это мощная, но легкая библиотека построения диаграмм.

$ yarn add recharts

Далее с помощью Recharts мы создадим повторно используемый компонент гистограммы. Поскольку подробный обзор Recharts выходит за рамки данной статьи, просто создайте новый файл в /src/components/BarChart.js и вставьте в него следующий код:

import React, { PureComponent } from 'react';
import {
  BarChart,
  Bar,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  Legend,
  ResponsiveContainer,
} from 'recharts';

const colorsList = ['#008f68', '#6db65b', '#4aae9b', '#dfa612'];

class ExampleChart extends PureComponent {
  render() {
    return (
      <div style={{ width: '100%', height: 350 }}>
        <ResponsiveContainer>
          <BarChart data={this.props.data}>
            <CartesianGrid strokeDasharray="2 2" />
            <XAxis dataKey="name" />
            <YAxis type="number" domain={[0, 10]} />
            <Tooltip />
            <Legend />

            {this.props.bars.map((bar, i) => (
              <Bar
                dataKey={bar}
                fill={colorsList[i]}
                key={`bar_${i}`}
              />
            ))}
          </BarChart>
        </ResponsiveContainer>
      </div>
    );
  }
}

export default ExampleChart;

Теперь у нас есть компонент гистограммы, поэтому нам просто нужно импортировать и использовать его на странице MDX, /src/pages/mdx-intro/index.mdx. Вот окончательная версия:

---
title: MDX is Magical!
path: /mdx-intro
date: 2019-08-25
---

import TitleBar from '../../components/TitleBar';
import PostSignature from '../../components/postSignature.mdx';
import BarChart from "../../components/BarChart";

export const myReviews = [
  {
    name: "Tim's Tacos",
    overall: 9,
    variety: 7,
    price: 8,
    taste: 9
  },
  {
    name: "Noodleville",
    overall: 7,
    variety: 5,
    price: 6,
    taste: 8
  },
  {
    name: "Waffle Shack",
    overall: 6,
    variety: 5,
    price: 4,
    taste: 6
  },
];

<TitleBar
  text={props.pageContext.frontmatter.title}
  size={'32px'}
  bkgdColor={'#4aae9b'}
/>


This page is built with turbo-charged Markdown!

#### My Food Reviews:

<BarChart
  data={myReviews}
  bars={["overall", "variety", "price", "taste"]}
/>

<PostSignature />

На вашей странице вы должны увидеть разноцветную анимированную гистограмму, которая даже имеет всплывающие подсказки при наведении курсора.

И все это внутри страницы Markdown (MDX)! Только представьте, сколько всего интересного вы можете создать с таким инструментом за короткое время.

Заключение

Мы многое рассмотрели в этом мануале по работе MDX. Как видите, комбинация MDX + Gatsby полностью меняет правила игры и позволяет разрабатывать веб-сайты значительно быстрее.

Тем не менее, мы рассказали только об основных функциях и возможностях. Рекомендуем вам самостоятельно порыться в документации Gatsby о MDX.

Tags: , , , ,

Добавить комментарий