Gatsby: Использование компонентов React в исходном коде Markdown

Созданный на 5 июн. 2016  ·  112Комментарии  ·  Источник: gatsbyjs/gatsby

Есть ли простой способ использовать компоненты React в моем исходном коде Markdown. Что-то вроде реакции ?

question or discussion

Самый полезный комментарий

Так что я всегда пытался придумать чистый способ смешивания React и Markdown. По крайней мере, с тех пор, как я начал работать над Гэтсби.

И наконец, я думаю, у меня есть идея, которая может сработать.

Мы бы использовали то же правило для различения обычных HTML-элементов и компонентов React, что и JSX, т.е. React пишется с большой буквы.

Итак, вы можете включить компоненты React прямо в свой Markdown, например

# Hi folks

I'm writing some markdown about speaker <Person id="Paul Ryan">Paul Ryan</Person> who's the speaker of the house and other stuff.

<InteractiveComponent invertedColors={true} allTheProps={true} />

Затем это будет проанализировано в AST примерно так:

[
  [{ raw: true, value: "<h1>Hi Folks</h1>" }],
  [
    { raw: true, value: "<p>I'm writing some markdown about speaker " },
    {
      raw: false,
      value: {
        name: "Person",
        props: { id: "Paul Ryan", children: "Paul Ryan" }
      }
    },
    { raw: true, value: " who's the speaker of the house and other stuff.</p>" }
  ],
  [
    {
      raw: false,
      value: {
        name: "InteractiveComponent",
        props: { invertedColors: true, allTheProps: true }
      }
    }
  ]
];

А затем в вашем компоненте вместо непосредственного рендеринга (опасный стиль) HTML вы вместо этого передадите его вспомогательной функции с сопоставлением с каждым компонентом React, например:

import React from "react";
import renderHtmlReact from "gatsby-render-html-react";
import Person from "../components/Person";
import InteractiveComponent from "../components/InteractiveComponent";

export default ({ data }) => (
  <div>
    {renderHtmlReact({
      ast: data.markdownRemark.ast,
      componentMap: { Person, InteractiveComponent }
    })}
  </div>
);

// Your query goes down here

Нам нужно было бы создать прототип, чтобы убедиться, что это работает с Remark, но я почти уверен, что React "Html" останется нетронутым. Так что нам просто нужен синтаксический анализатор, чтобы разделить HTML и превратить части React JSX в данные, а также интерфейсную библиотеку для рендеринга результирующего «AST».

Мысли?

Все 112 Комментарий

Это отличная идея. Я был бы готов поработать, если он еще не доступен.

Я разработчик responsedown. Было бы здорово увидеть, как responsedown работает с Гэтсби. Напишите мне, если у вас возникнут вопросы или вам понадобится помощь в его интеграции.

👍 это обычная просьба, поэтому было бы здорово иметь что-то работающее и широко доступное!

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

https://github.com/benstepp/gatsby-reactdown

Спасибо, я попробую и расскажу, как все прошло.

О, круто! Хороший Бен. Это намного проще в настройке, чем я представлял
ха-ха. Отличная работа, Андрей.

Во вторник, 7 июня 2016 г., в 22:31 Джо Минен [email protected] написала:

Спасибо, я попробую и расскажу, как все прошло.

-
Вы получили это, потому что оставили комментарий.

Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/gatsbyjs/gatsby/issues/312#issuecomment -224492088,
или отключить поток
https://github.com/notifications/unsubscribe/AAEVh-2doZe_FXFMBxYTJ5FAVqo4XqxNks5qJlO6gaJpZM4Iubim
.

@benstepp здорово! Это выглядит достаточно просто при использовании файлов Markdown через оболочку, но будет ли это работать при импорте файла уценки для использования внутри компонента React?

Изменить: кажется, что он должен работать из коробки, но каким-то образом компонент React, в который преобразован файл md ничего не выводит ...

Я думал о другом подходе, который открывает новый слой GraphQL (# 420). Я открыл вопрос, спрашивая об этом в репозитории mdash https://github.com/wooorm/mdast/issues/13

Было бы здорово! Я чувствовал, что был так близок к Reactdown… Файлы уценки правильно преобразованы в компоненты React с помощью webpack (по крайней мере, так выглядит), но он просто дает мне пустые компоненты, когда я использую их в своем коде.

@SachaG есть репо, где я могу взглянуть?

Вау, действительно странно. Пытался создать репродукцию выпуска, и теперь все работает! Даже не знаю, что изменилось ... Не могу жаловаться, наверное :)

Боги React спустились на золотой колеснице, и вот! код работал

@SachaG Я помню, были некоторые проблемы с тем, как responsedown ссылается на время выполнения. В любом случае, если вы столкнетесь с некоторыми проблемами, я буду уверен, что помогу.

Здравствуйте! Были ли здесь какие-нибудь обновления в последнее время? Каков рекомендуемый метод использования компонентов React в уценке? Есть ли пример, которому я могу следовать? Благодаря!

Пока нет :-( У меня есть хороший план, как это сделать - в основном скомпилируйте файл уценки в файл компонента React, где вы правильно обрабатываете импорт всех компонентов React, на которые есть ссылки, но пока не нуждаетесь в его создании. Не стесняйтесь начни работать, если тебе это нужно!

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

В идеале это был бы плагин для Gatsby v1, который выполнял бы эти шаги
автоматически.

Во вторник, 2 мая 2017 г., 12:50 Пиюш Сингх [email protected] написал:

@KyleAMathews https://github.com/KyleAMathews ты имеешь в виду, что я должен бежать
скрипт конвертера в моем файле уценки, а затем добавьте другой ответ
компоненты, которые мне нужны для выходного файла, созданного на этапе преобразования? однажды
это сделано то делать финальную сборку?

-
Вы получаете это, потому что вас упомянули.

Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/gatsbyjs/gatsby/issues/312#issuecomment-298741837 ,
или отключить поток
https://github.com/notifications/unsubscribe-auth/AAEVh4riB8uXgeRUybcR6OxsC1EAKnkKks5r14kPgaJpZM4Iubim
.

Простой пример того, что я имею в виду.

Представьте, что у вас есть файл уценки на /my-blog/index.md, который выглядит следующим образом:

---
title: "hi folks"
---

# This is my broomstick

Yo yo foo

<SweetComponent props="super cool" />

Затем тело может быть преобразовано в компонент реакции, который будет запускаться через webpack / babel / и т. Д. как обычно.

import React from 'react'
import SweetComponent from 'auto-resolve-this-somehow'

class MarkdownBody extends React.Component {
  render () {
    return (
      <div>
        <h1>This is my broomstick</h1>
        <p>Yo yo foo</p>
        <Sweet Component props="super cool" />
      </div>
    )
  }
}

Уловка состоит в том, как интегрировать это с системой Gatsby graphql. В идеале вы могли бы просто запросить «компонентную» версию файла уценки, аналогично тому, как вы можете запросить html сегодня.

В любом случае, это краткий набросок того, о чем я думал.

@KyleAMathews, спасибо, я думаю, теперь я понял.

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

Если вы видите здесь источник html, страница использует jQuery для некоторых ползунков управления, хотя я думаю, что могут быть лучшие способы делать вещи jQuery с компонентами React?

Исходя из того, что я собрал до сих пор, я полагаю, что создание такого контента с помощью фреймворка Gatsby возможно гораздо более аккуратно и структурированно, верно?

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

@KyleAMathews , я думал о предложенном вами решении ..

Как вы думаете, можно ли использовать или улучшить что-то вроде markdown-it-jsx для преобразования в желаемую структуру компонентов MD JS?

Для разрешения части auto-resolve-this-somehow , возможно, второй синтаксический анализатор может просканировать файл компонента MD JS, чтобы найти JSX, который соответствует тем, что в списке реестра компонентов (который может быть простым текстовым файлом или поиском файла в каталоге, где все компоненты будут сохранены), а затем добавить соответствующую строку импорта в начало файла?

Я собираюсь начать работу над этим, так что любые отзывы будут отличными!

Обратите внимание: есть еще один проект, который этим занимается, может быть, он будет полезен в качестве справки: react-styleguidist . Пример файла уценки

Включение компонентов в markdown напоминает мне этот шедевр Брета Виктора.

UPD: и еще один пример: mdxc

И еще один http://thejameskyle.com/react-markings.html

Решение использует react-jsx-parser .
На сайте howtographql.com мы используем его в производстве: https://github.com/howtographql/howtographql/blob/master/src/components/Tutorials/Markdown.tsx#L182

Один недостаток: это, конечно, медленнее, чем просто использование dangerouslySetInnerHTML , потому что это

  1. Разбирает HTML
  2. Строит виртуальное доменное дерево
  3. Визуализирует виртуальное дерево с помощью React

Один из способов ускорить это - не отправлять необработанный html с запросом graphql, а фактически отправлять формат, который используют документы Inferno.js, как описано здесь .

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

Это означало бы

  1. Создавайте правильные типы GraphQL, это не должно быть проблемой, поскольку типы GraphQL могут быть рекурсивными и представлять собой дерево.
  2. После того, как бизнес по разбору remark markdown будет выполнен, сгенерируйте сериализованный формат jsx.
  3. В React десериализуйте этот формат.

Другой вариант, который я присмотрел, - https://github.com/mapbox/jsxtreme-markdown

Мы могли бы использовать аналогичный образец. Просто конвертируйте Markdown в компоненты JSX. Используйте настраиваемые разделители для добавления JavaScript и JSX. Мы могли бы прекрасно использовать нашу существующую настройку Remark. И это не сильно снизит производительность, поскольку это будут обычные страницы React.

Также есть https://github.com/cerebral/marksy , который я недавно использовал с хорошими результатами.

Есть ли для этого рекомендуемый подход в контексте Гэтсби или это еще предстоит решить?

Привет, есть какие-нибудь рекомендации по включению таможенных компонентов в наши файлы уценки gatsby?

Еще один вариант в коллекции https://idyll-lang.github.io/

Похоже, marksy отлично подходит для этого

поскольку он возвращает дерево элементов реакции, мне интересно, как я могу интегрировать это в плагин gatsby?

@KyleAMathews @revolunet Что вы думаете о регистрации компонентов, которые нам нужно использовать в качестве настраиваемых элементов, после чего мы можем просто включить их в сообщение в блоге, а остальную работу оставить браузеру?

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

@abdulhannanali Регистрация компонентов, доступных в разметке, - хорошая идея, но материал с настраиваемыми элементами не очень

Так что я всегда пытался придумать чистый способ смешивания React и Markdown. По крайней мере, с тех пор, как я начал работать над Гэтсби.

И наконец, я думаю, у меня есть идея, которая может сработать.

Мы бы использовали то же правило для различения обычных HTML-элементов и компонентов React, что и JSX, т.е. React пишется с большой буквы.

Итак, вы можете включить компоненты React прямо в свой Markdown, например

# Hi folks

I'm writing some markdown about speaker <Person id="Paul Ryan">Paul Ryan</Person> who's the speaker of the house and other stuff.

<InteractiveComponent invertedColors={true} allTheProps={true} />

Затем это будет проанализировано в AST примерно так:

[
  [{ raw: true, value: "<h1>Hi Folks</h1>" }],
  [
    { raw: true, value: "<p>I'm writing some markdown about speaker " },
    {
      raw: false,
      value: {
        name: "Person",
        props: { id: "Paul Ryan", children: "Paul Ryan" }
      }
    },
    { raw: true, value: " who's the speaker of the house and other stuff.</p>" }
  ],
  [
    {
      raw: false,
      value: {
        name: "InteractiveComponent",
        props: { invertedColors: true, allTheProps: true }
      }
    }
  ]
];

А затем в вашем компоненте вместо непосредственного рендеринга (опасный стиль) HTML вы вместо этого передадите его вспомогательной функции с сопоставлением с каждым компонентом React, например:

import React from "react";
import renderHtmlReact from "gatsby-render-html-react";
import Person from "../components/Person";
import InteractiveComponent from "../components/InteractiveComponent";

export default ({ data }) => (
  <div>
    {renderHtmlReact({
      ast: data.markdownRemark.ast,
      componentMap: { Person, InteractiveComponent }
    })}
  </div>
);

// Your query goes down here

Нам нужно было бы создать прототип, чтобы убедиться, что это работает с Remark, но я почти уверен, что React "Html" останется нетронутым. Так что нам просто нужен синтаксический анализатор, чтобы разделить HTML и превратить части React JSX в данные, а также интерфейсную библиотеку для рендеринга результирующего «AST».

Мысли?

А затем в вашем компоненте вместо непосредственного рендеринга (опасный стиль) HTML вы вместо этого передадите его вспомогательной функции с сопоставлением с каждым компонентом React, например:
[…]
Мысли?

Мы тоже этим занимаемся (очень упрощенно, небезопасно и разработано только для определенных тегов). Нашим вариантом использования было оформление / макет документа JSON:

<IconGrid src="sensors.json" />

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

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

<Api method="post" description="
An API which uses **markdown**.

And having multi line parameters would be helpful as well.
" />

Попробовав массу вещей в этом пространстве, я убедился, что да, это действительно нужно решить на уровне уценки. Это означает, что вкус уценки действительно должен понимать jsx / react. Проблема на самом деле в том, что jsx поддерживает интерполяцию javascript, а уценка подавляется. Jsxtreme-markdown приближается и работает над этим, сначала обрабатывая их, а затем используя markdown для анализа остальных. Другой подход состоит в том, чтобы опираться на естественную способность парсеров MD обрабатывать html и, следовательно, простой jsx (например, Marked будет обрабатывать элементы в верхнем регистре), но вы быстро столкнетесь с раздражающими ограничениями, когда застревает только на строковых реквизитах и ​​нет вложенной уценки (например, Markdown внутри , реквизит. дети). Другая проблема заключается в том, что гидратация на клиенте раздражает, так как вам нужна среда выполнения (и, как правило, довольно большая) для преобразования строки в элементы реакции, что не идеально для сосредоточения Гэтсби на быстром взаимодействии и производительности.

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

Просто добавляю свои 2 цента!

Еще до того, как я узнал о существовании Gatsby (2 года назад), я попытался создать генератор статических сайтов, который ведет себя аналогично jekyll (

Я решил использовать регулярное выражение, чтобы найти <CapitalizedComponents/> в содержимом уценки, и это сработало очень хорошо, за исключением нескольких крайних случаев. В то время я использовал mark, у которого были некоторые странные побочные эффекты при синтаксическом анализе html.

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

<Component>
   <Child/>
</Component>

В любом случае, я очень рад, что Гэтсби поддержит это! Я в процессе преобразования своего сайта jekyll в gatsby, и я почти закончил. Моя следующая задача - выяснить, как заменить мои jekyll-файлы в сообщениях блога md на компоненты в моей версии gatsby.

@jquense соглашается, что dangerouslySetInnerHTML на props.children .

Это не стопроцентное решение, но оно подойдет для многих настроек. Я также не большой поклонник идеи написания JS внутри уценки. Таким образом, вы теряете все инструменты поддержки.

@jakedeichert да, простое регулярное выражение идет пока что. Круто у вас получилось нечто похожее на это рабочее! Это подтверждает концепцию. Мы хотели бы использовать парсер JS, который понимает JSX, для извлечения структурированной информации. Таким образом, мы могли поддерживать вложенные компоненты.

@KyleAMathews Как продвигается то, что вы предложили?

Несколько мыслей по этому поводу:

  1. У меня есть рабочий пример, в котором используется замечание для преобразования разметки, содержащей произвольные компоненты реакции tmp-comment-jsx . Я использовал remark-html и hast-util-to-html качестве базовых проектов.
    Вот пример использования + вывод: пример
    Я могу предоставить дополнительную информацию о том, как это работает, если вам интересно.
  2. MapBox создал пакет « комментарий-реакция», который преобразует разметку в элементы реакции с помощью комментария. Может потребоваться некоторая работа, чтобы адаптировать пакет для принятия настраиваемых элементов реакции.

Никто еще не начал над этим работать.

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

Итак, для работы с GraphQL вам понадобится клиентская среда выполнения для создания компонентов React. Мое предложение пришло из проработки дизайна, который обеспечит минимально возможное время выполнения.

Думаю, теперь я понял. Итак, по вашему мнению, необходимы два фрагмента кода:

  1. markdown -> готов к использованию HAST, поддерживающий реагирующие компоненты. (Этот код должен запускаться во время сборки?)
  2. React enabled HAST -> элемент реакции (он должен работать на стороне клиента с минимальным / тривиальным временем выполнения)

Я правильно понимаю? Я что-то упускаю?

Ага!

Пробежался по другому проекту в этом пространстве - есть несколько интересных идей https://github.com/luiscarli/md-to-react

Привет,

Я делаю еще один удар. У меня есть рабочий пример первой части, которая создает HAST здесь замечание-custom-element-to-hast . Он по-прежнему должен поддерживать использование markdown в качестве дочерних элементов и, возможно, загрузчика веб-пакетов, который его использует.

@KyleAMathews Как вы думаете, этот подход соответствует вашему мнению?

Что касается второй части, мы можем использовать синтаксическое дерево / hast-to-hyperscript . Вот пример использования wooorm / rebec-vdom .

@ fazouane-marouane круто! Да, с первого взгляда это кажется очень близким. Отличная работа!

Мы не хотим использовать hast-to-hyperscript во внешнем интерфейсе, так как он имеет множество зависимостей, и мы хотим, чтобы среда выполнения была как можно более легкой - например, просто рекурсивно просматривайте AST, создавая элементы React. Так что переместите столько же из второй библиотеки в свой модуль.

@KyleAMathews Тогда здорово! Я постараюсь сделать оставшиеся шаги в ближайшие дни. Надеюсь, это приблизит нас к практическому решению.

Привет, @ fazouane-marouane и @KyleAMathews , я прочитал ваше обсуждение и реализовал "простые" версии различных частей, которые вы описали здесь, в этом приложении, над которым я работаю.

Интересны те части, которые используют код @ fazouane-marouane в форме плагина gatsby здесь, и часть, где мы рендерим HAST здесь . Также может быть интересно посмотреть, как извлекается HAST благодаря GraphQL.

Обратите внимание, что на момент написания этого комментария он далек от совершенства, оптимизирован и чист.

РЕДАКТИРОВАТЬ: мой компонент renderHAST в значительной степени вдохновлен тем, как phenomic работает с уценкой рендеринга на стороне клиента: https://github.com/phenomic/phenomic/blob/master/packages/plugin-renderer-react/src /components/BodyRenderer.js

@pbellon Спасибо, что присоединились! Это сэкономит всем много времени. Код, кажется, делает то, что нужно для остальных шагов. Попробую сегодня вечером.

Одна вещь, которую мне нужно отладить, - это способ обработки дочерних компонентов.
Прямо сейчас, если я установлю запись в уценке This is a test <MyComponent>let's see how children are handled</MyComponent> children свойство MyComponent children будет установлено в [0, null] .

Но я не уверен, исходит ли это от парсера или от того, как я увлажняю HAST.

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

@ fazouane-marouane Понятно. Со своей стороны я постараюсь поиграть с вашим кодом, чтобы посмотреть, смогу ли я реализовать эту функцию (и сделать пиар, если мне это удастся), но это не кажется тривиальной модификацией 😮
Я создал проблему с вашим репо здесь

Вкладываю свои 0,02 доллара. В рамках разработки GitDocs нам нужен был способ позволить пользователям встраивать JSX в файлы разметки. Вот что у меня есть на данный момент.

Разбор Markdown

Обработка уценки использует унифицированное , замечание и повторное написание . Пользовательский токенизатор был разветвлен из HTML-токенизатора блока комментариев с дополнительным регулярным выражением для обнаружения JSX. Этот токенизатор позволяет повторно определять блоки JSX как raw для дальнейшей обработки.

Я написал собственный плагин rehype, который работает аналогично rehype-raw, но поддерживает JSX и некоторую базовую оценку выражений. Плагин находит узлы raw и определяет, являются ли они JSX, пытаясь проанализировать блок с помощью acorn-jsx . Если синтаксический анализ успешен, JSX AST, созданный acorn, преобразуется в HAST.

Поддерживаемый JSX

Пока я могу преобразовать следующие биты JSX (примеры примеров взяты из набора тестов)

<Test>
  <Test2></Test2>
</Test>
<Test>some text</Test>
<Test attr={{ prop: 400 }} />

Выражения

Поддерживается простая оценка выражения во время компиляции.

<Test attr={1 + 2}/>

Созданный узел HAST будет иметь свойство 'attr' установленное на 3 .

Выражения массива

Использование Array.prototype.map() разрешено в свойствах:

<Test attr={ [1,2,3].map(x => 2 * x) } />

Вы даже можете сопоставить массив и создать дочерние элементы JSX

<Test>{ [1,2,3].map(x => (<Test2>{x}</Test2>)) }</Test>

будет переведено на HAST как эквивалент

<Test>
  <Test2>1</Test2>
  <Test2>2</Test2>
  <Test2>3</Test2>
</Test>

Ограничения

Поддержка выражений довольно ограничена и не проверялась на безопасность. Код не использует eval и доступ к таким вещам, как window не должен быть возможен, но я не могу дать никаких гарантий.

Я провел эксперимент в этой области, где вы можете в полной мере использовать плагины Gatsby Remarks как обычно. Вы передаете graphql html загрузчику веб-пакетов, который создает код response.js. К сожалению, у него есть несколько проблем, и он ломает отдельные производственные сборки.

          createPage({
            path: edge.node.fields.slug,
            component: getCdResolve(blogPost, edge.node.fileAbsolutePath, {
              html: edge.node.html,
              site: result.data.site,
            }),
            context: {
              slug: edge.node.fields.slug,
            },
          })

Где cdResolve возвращает строку вида !!cd-resolve-loader!foo.md . Гэтсби это не нравится. По крайней мере, это работает на сервере разработки.

Остальной код здесь .

Результат сборки - это простой компонент с набором статических узлов для детей.

var h = require('react').createElement;
var n1 = h('div', { key: 1, dangerouslySetInnerHTML: { __html: '<h1>Hello</h1>' } });
var n2 = h(CustomComponent, { key: 2, foo: 1 });

module.exports = () => h('div', null, [n1, n2]);

Да интересно!

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

Ага, это была другая проблема. Я думаю, если бы проблемы были как-то решены, это был бы один из лучших конечных результатов с точки зрения размера пакета и времени для интерактивности. Конечно, это далеко не рабочее решение. Любые советы о том, как получить компиляцию в файлы JS после работы с замечаниями?

@brigand Я думаю, что самое простое решение - это то, что я изложил в предыдущем комментарии https://github.com/gatsbyjs/gatsby/issues/312#issuecomment -336681894

@KyleAMathews Для предложенного вами решения теперь мы знаем, как преобразовать разметку, содержащую jsx, в html AST, используя реплики. Мы устранили последнюю ошибку блокировки. Все, что нам сейчас нужно, это создать код, который может преобразовать этот AST в компонент реакции и отправить его в npm. К концу следующей недели у меня будет немного свободного времени.

Не стесняйтесь появляться на пороге с бейсбольной битой, если я к тому времени что-нибудь не толкну 😅.

@ r24y заработал !!! Ознакомьтесь с его PR https://github.com/gatsbyjs/gatsby/pull/3732 и примерной страницей на сайте с примером использования-примечания!

https://using-remark.gatsbyjs.org/custom-components/

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

Всего у нас два пакета:
Разбор в HAST: @ dumpster / comment-custom-element-to-hast
Тривиальный рендеринг в компонент React :

@pbellon предложил здесь плагин Gatsby.

Этот конвейер должен быть более снисходительным, чем пересказывать. Если мне не изменяет память, rehype использует parser5, который не принимает <Note value="my content" /> и я не могу вспомнить, принимает ли он тела для пользовательских элементов.

@KyleAMathews Я не уверен, что

@ fazouane-marouane потрясающе !!!

Я думаю, что следующим шагом будет добавление примера сайта в репозиторий, чтобы мы могли также продемонстрировать вашу работу - тогда нам нужно создать страницу документации на gatsbyjs.org, чтобы поговорить о различных вариантах и ​​компромиссах, которые они имеют.

Сладкий ! Спасибо за разъяснения.

Я постараюсь найти что-нибудь на следующую неделю или неделю после (начинаю новую работу в этот понедельник 😅).

Присоединяйтесь. Прочитав https://using-remark.gatsbyjs.org/custom-components/ и попробовав его, я создал небольшой пакет с именем gatsby-comment-component, чтобы избежать предупреждений validateDOMNesting, которые вы получаете, если ваш компонент находится внутри вашей уценки. содержит элементы уровня блока (div ...). Пользовательские компоненты по умолчанию помещаются в абзац, тогда как в этом пакете они помещаются в div.
Довольно легко использовать

//In your gatsby-config.js
plugins: [
  {
    resolve: "gatsby-transformer-remark",
    options: {
      plugins: [
        {
          resolve: "gatsby-remark-component",
          options: { components: ["my-component", "other-component"] }
        }
      ]
    }
  }
]

Надеюсь, это кому-то будет полезно.

@Hebilicious спасибо за плагин; да, я понял, что все пользовательские компоненты были отрисованы внутри элемента <p> и я использовал,

<div>
  <custome-component></custom-component>
</div>

как обходной путь.

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

@ li-xinyang Я согласен с вами. Я добавил функцию автоматического определения, поэтому вам не нужно добавлять их вручную.
Обязательно обновите пакет до последней версии 1.1.0, если хотите попробовать.
Готово к работе с:

//In your gatsby-config.js ...
plugins: [
  {
    resolve: "gatsby-transformer-remark",
    options: {
      plugins: ["gatsby-remark-component"]
    }
  }
]

Это немного касательно, но люди здесь могут быть заинтересованы в сотрудничестве с @rauchg : см. Предложение

@ r24y звучит

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

Я не знаю, знаете ли вы о проекте под названием Catalog, который также поддерживает встраивание компонентов React в Markdown . Существует также плагин Gatsby, называемый gatsby-comment-design-system, который пытается адаптировать концепцию каталога.

Это решение выглядит идеально @arcticicestudio

Каталог выглядит красиво; И плагин gatsby-remar-design-system - это круто, но он не поддерживает компоненты React. Я действительно думаю, что он что-то делает правильно, он использует существующий синтаксис блока кода, чтобы добавить более сложные функции в Markdown.

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

 # Some Heading
 ... и т.д ...

&lt;Example>
   &lt;Etc />
&lt;/Example>

Когда мы хотим, чтобы отображался встроенный элемент react , мы указываем язык как react , и включается синтаксический анализатор, поддерживающий JSX, и генерирует действительный AST, который можно использовать с пересказом. Если нам нужен обычный пример призмы JavaScript, просто используйте нормальный язык javascript .

Привет, ребята, отличное обсуждение.
Я использую gatsby-remark-component и у меня есть несколько вопросов:

  1. Есть ли способ «автоматически определять» компоненты? Это устранило бы необходимость явного информирования моих компонентов в объекте компонентов:
const renderAst = new RehypeReact({
  createElement: React.createElement,
  components: {

  },
}).Compiler
  1. Есть ли способ интегрировать некоторые изображения с gatsby-remark-images ? Одна из моих целей состоит в том, чтобы пользователь мог добавить изображение и отправить его в мой компонент, например, через props. Что-то вроде:
    <my-component header-image="[](./image.png)"><my-component>

Благодаря!

@ThiagoMiranda Да, (2) было бы здорово! Мой вариант использования - галерея изображений:

<gallery>
  <item source="image1.jpg" caption="One"></item>
  <item source="image2.jpg" caption="Two"></item>
</gallery>

Этот парсер уценки JSX от Zeit выглядит многообещающим: https://github.com/mdx-js/mdx

MDX - это надмножество спецификации CommonMark, которая добавляет встроенный JSX и синтаксис импорта / экспорта.

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

Я написал плагин для mdx: https://github.com/nhducit/gatsby-plugin-mdx

круто, хотел попробовать с Гэтсби :)

Используя плагин mdx от @nhducit , довольно просто подключить страницы MDX !!

  1. Добавьте конфигурацию для mdx и источник в директорию pages/ .

gatsby-config.js

module.exports = {
  plugins: [
    'gatsby-plugin-mdx',
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        name: 'pages',
        path: `${__dirname}/src/pages/`,
      },
    },
  ],
}
  1. Запросите все файлы уценки и создайте страницы для каждого из них.

gatsby-node.js

exports.createPages = ({ graphql, boundActionCreators }) => {
  const { createPage } = boundActionCreators

  return new Promise((resolve, reject) => {
    graphql(`
      { 
        allFile(filter:{extension:{eq:"md"}}) {
          edges {
            node {
              absolutePath
              relativeDirectory
              name
            }
          }
        }
      }
    `).then(result => {
      if (result.errors) {
        return reject(result.errors)
      }

      // Create markdown pages.
      result.data.allFile.edges.forEach(({ node: {
        absolutePath,
        relativeDirectory,
        name
       } }) => {
        createPage({
          path: `/${relativeDirectory}/${name}`,
          component: absolutePath
        })
      })
    })
    .then(resolve)
  })
}
  1. Использовать многомерные выражения 🎉

src/pages/my-markdown-page.md

import MyComponent from '../components/MyComponent'

# Title

_some content_

<MyComponent />

@avigoldman Здорово ! Было бы здорово, если бы ваш пример был добавлен в README плагина @nhducit .

@avigoldman PR приветствуется! 👍

@avigoldman похоже, что этот подход конфликтует с фронтматтером?

@nhducit Сделаю пиар!

@lintonye, можешь

@lintonye вы пробовали использовать экспорт mdx? Похоже, это эквивалент mdx: https://github.com/mdx-js/mdx#exports

Поправьте меня, если я ошибаюсь, но похоже, что нам нужно дождаться Gatsby 2.0 с более поздней версией webpack, чтобы передать плагины замечаний в MDX.

cc @KyleAMathews

@avigoldman @nhducit При экспорте данных из файлов mdx с использованием синтаксиса экспорта, как мы можем получить к ним доступ в нашем пользовательском интерфейсе, когда компоненты визуализируются?

тот же вопрос здесь, с MDX в настоящее время, не смог:

  • применять пользовательские стили к страницам уценки
  • вводить содержимое frontmatter как pathContext из именованных экспортов mdx
    Это можно было бы сделать на самом деле, но для этого требуется создать файл .js для импорта файла .md для каждого файла .md, поэтому он дублирует работу ...

@slorber У меня есть довольно хакерское решение в этом репо: https://github.com/avigoldman/avigoldman.com

Определенно не идеально. Я собираюсь вернуться к этому, когда выйдет Gatsby V2.

Привет и спасибо @avigoldman

Я тоже пытался сделать это здесь https://github.com/nhducit/gatsby-plugin-mdx/issues/13#issuecomment -392334706

Кажется, вы нашли недостающий фрагмент, который мне не нужно было правильно извлекать из экспорта: babel-plugin-config-export

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

А как насчет публикации вашего плагина в NPM? это кажется более удобным, чем тот, который @nhducit сделал в отношении передней части

Кроме того, откуда взялся фрагмент ... mdx graphql?

Что касается MDX, они просто добавили «MDXProvder» (на основе React Context), который может быть полезен для интеграции пользовательских тегов с Gatsby, cc @avigoldman

@slorber Я создал плагин gatsby-transformer-mdx, чтобы я мог запрашивать файлы MDX.

Я рассматриваю каждый макет как страницу, а каждый файл MDX как содержимое. Таким образом, макет получает контекст страницы, а затем добавляется многомерное выражение (как и в случае с HTML-кодом, сгенерированным примечаниями).
Это не будет работать в Gatsby V2, так как специальные компоненты макета исчезнут.

MDXProvider выглядит многообещающе!

Добавив сюда свои 2 цента, мне удалось взломать большую часть моего собственного веб-сайта (репо все еще использует Jekyll, скоро будет обновлять или добавлять новое репо) на Gatsby с использованием mdx, благодаря gatsby-transformer-mdx @ avigoldman!

Замечательно! У вас должно быть время на этих выходных / предстоящей неделе, чтобы превратить его в пакет, который хорошо работает с Gatsby V2.

@avigoldman одна вещь, которую я не мог понять из вашего gatsby-transformer-mdx, - это этап рендеринга. gatsby-transformer-comment использует поле html (которое является строкой), что использует ваш трансформатор? Как работает загрузчик веб-пакетов, если они нигде не требуются?

О, я только что прочитал комментарии выше, трюк в том, что Gatsby v1 автоматически оборачивает все в компонент макета, поэтому вы используете absolutePath для нацеливания на файл MDX. 😃 Спасибо за этот трюк!

@avigoldman есть новости о плагине Gatsby 2? Было бы также замечательно, если бы вы могли дать приблизительные инструкции о том, как вы могли бы построить его без компонента макета, которого больше нет в Gatsby 2.
Благодаря!

Я надеялся, что смогу каким-то образом использовать функцию MDX export default , но передача каких-либо дополнительных свойств, кроме children , кажется невозможной для ATM. mdx-js / mdx # 187

Если мой PR будет объединен (mdx-js / mdx # 189), я думаю, мы сможем использовать MDX с существующими gatsby-plugin-mdx и gatsby-transformer-mdx. Единственное необходимое изменение будет на нашей стороне, и это экспорт нашего шаблона сообщения из наших файлов .mdx :

src/posts/hello-world.mdx :

import Post from '../components/post'

# Hello World

Lorem ipsum.

export default Post

gatsby-node.js :

const path = require('path')

exports.createPages = ({ actions }) => {
  actions.createPage({
    path: '/posts/hello-world',
    component: path.join(__dirname, 'src', 'posts', 'hello-world.mdx'),
    context: { /* passed as pageContext */ }
  })
}

src/components/post.js :

import React from 'react'
import Layout from './layout'

export default ({ children, pageContext }) => (
  <Layout>
    {children}
  </Layout>
)

Я думаю, это действительно критично. Прямо сейчас все плагины gatsby-remark-* ~ повторно реализуют кучу логики рендеринга, которая может и, вероятно, должна быть в React. Это могло бы многое упростить.

@DylanVann, это как-то зависит. Плагины gatsby-remark-* выполняют множество преобразований во время сборки, которые, если бы мы выполняли их в React, означали бы доставку большого количества JS в браузеры. Также вещи, которые невозможно сделать в React, например https://www.gatsbyjs.org/packages/gatsby-remark-images/?=remark-image

В идеале, конечно, мы смешиваем оба мира.

@KyleAMathews Да, это будет означать, что на стороне клиента будет больше JS, хотя сначала он будет поставляться как статический HTML. Я думаю, что многие люди, вероятно, в любом случае отправляют gatsby-image для некоторых частей своего сайта, так что в этом случае дублирование не является проблемой.

Я понимаю, что в плагинах gatsby-remark-* есть утилита. В частности, логика рендеринга, которая в настоящее время выполняется со строками, кажется, может быть реализована в React.

У меня такая работа с методом htmlAst / rehype-react .

Вроде так, но на практике все намного сложнее. Если вы верите, что знаете что-то, вы можете поднять новый вопрос, сформулировав конкретное предложение.

Кажется, решить эту проблему сложно. К сожалению, не думаю, что у меня будет время что-то реализовать или внести предложение. Идея создания плагинов remark частично с использованием пользовательских компонентов React определенно работает, у меня есть код, использующий это.

Это генерируется @dylanvann/gatsby-remark-cloudinary из изображений уценки, заканчивающихся на mp4 . Идея в том, чтобы оптимизировать видео (размер во время сборки, добавление постеров). Однако мне нужна логика рендеринга в React. Обработка видео выполняется другой функцией, но это часть того, чем заменяется HTML-код узла.

export const videoHTML = ({
    srcVideo,
    srcVideoPoster,
    base64,
    paddingBottom,
    presentationWidth,
}) =>
    `<cloud-video srcvideo="${srcVideo}" srcvideoposter="${srcVideoPoster}" base64="${base64}" paddingbottom="${paddingBottom}" presentationwidth="${presentationWidth}"></cloud-video>`

Затем с помощью специального компонента с rehype-react .

import React from 'react'
import rehypeReact from 'rehype-react'
import CloudVideo from './CloudVideo'

const renderAst = new rehypeReact({
  createElement: React.createElement,
  components: {
    'cloud-video': CloudVideo,
  },
}).Compiler

const Markdown = ({ ast }) => renderAst(ast)

Markdown.propTypes = {
  ast: PropTypes.object,
}

export default Markdown

AS можно вытащить из GraphQL.

Таким образом, этот компонент работает для SSR и на стороне клиента. В любом случае, я знаю, как обстоят дела с OSS. Я просто говорю, что думаю, что это была бы отличная функция и могла бы уменьшить сложность кода, поэтому было бы здорово, если бы у кого-то было время найти лучшие решения.

Я не возражаю ни с чем, что вы говорите, я думаю, что начать хорошее обсуждение было бы гораздо лучше в отдельном вопросе, чем в конце очень загруженной ветки из 60+ комментариев. 😉

Я и @avigoldman создали gatsby-mdx для размещения амбициозных интеграций и утилит MDX, совместимых с 2.0.

В настоящее время страницы gatsby .mdx работают по умолчанию после включения плагина, и к mdx были добавлены следующие дополнительные функции:

  • Используйте и запрашивайте классический интерфейс и интерфейс в стиле JSON
  • Определите макеты по умолчанию для файлов MDX, которые не определяют его

Мы также планируем более сложные интеграции для

  • расширенная обработка изображений
  • настраиваемые плагины md и hast.
  • совместимость со всеми теми же полями, что и gatsby-transformer-comment

Мы все еще на раннем этапе жизненного цикла, поэтому дайте нам знать, если у вас возникнут какие-либо проблемы, и мы сделаем это :)

@ChristopherBiscardi предназначен ли он для использования в сочетании с gatsby-plugin-mdx или вместо него?

@silvenon Похоже, что gatsby-plugin-mdx устарел и, следовательно, остановится на 1.0, а gatsby-mdx продвинется с 2.0 и выше.

@ m-allanson думает, что теперь, когда у нас есть gatsby- mdx, безопасно закрыть эту проблему?

Я так думаю, спасибо всем

Итак, может ли теперь gatsby-mdx быть предпочтительнее, чем rehype-react в сочетании с gatsby-transformer-remark как описано здесь ?

Если ответ не является однозначным «да», может ли кто-нибудь объяснить преимущества и недостатки обоих подходов?

Я думаю, что эта часть сообщения в блоге отвечает на ваш вопрос. rehype-react предоставляет пользовательские элементы HTML, которые сопоставляются с компонентами React, но MDX фактически является JSX внутри Markdown, он более предсказуем и имеет меньше недостатков.

Я не в команде Gatsby, но я бы сказал, что да, gatsby-mdx - предпочтительный способ React в Markdown.

@janosh, насколько мне известно, gatsby-mdx еще не может полностью заменить gatsby-transformer-comment
похоже, все еще скучает, например, gatsby-remar-images & gatsby-remar-copy-connected-files и другие плагины gatsby-mark ..
Я думаю, они работают над этим, но не уверены в текущем состоянии

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

@CanRau Сегодня я перебазирую это (https://github.com/ChristopherBiscardi/gatsby-mdx/pull/68) с намерением объединить и выпустить. Вероятно, нам придется иметь дело с некоторыми крайними случаями, но я рассмотрю некоторые из них сегодня на стриме, прежде чем объединиться.

Состояние PR состоит в том, что плагины gatsby-comment- * применяются правильно, но есть различия в том, как вывод, скажем, плагина gatsby-remar-prismjs (который в настоящее время производит вывод HTML) обрабатывается transformer-comment vs mdx's трубопровод. Я считаю поддержку таких плагинов, как gatsby-comment-prismjs, важной, но при этом неоптимальным подходом. Лучшим подходом в мире многомерных выражений является использование чего-то вроде prism-react-renderer в качестве элемента code в MDXProvider , что даст вам полную гибкость и контроль над рендерингом по сравнению с использованием Плагины замечаний для достижения аналогичного эффекта (а также позволяют вам делиться этим компонентом с содержимым, отличным от MDX, например страницами .js).

Меня гораздо больше беспокоит работа с копируемыми связанными файлами и обработкой изображений, чем с prismjs, работающими над первым выпуском поддержки плагина gatsby-comment- *.

Звучит потрясающе, @ChristopherBiscardi, особенно копирование связанных файлов и поддержка изображений, я хотел бы помочь, но, если честно, я не думаю, что смогу справиться с этим прямо сейчас, поскольку мы действительно упакованы ^^
Может быть, я могу поделиться некоторыми отзывами, я думаю, что попробую несколько небольших мета-страниц, чтобы попробовать что-то

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

Рад, что вы поможете в любой момент в будущем, если у вас будет время, не стесняйтесь пинговать меня, если у вас есть вопросы :) Обратная связь сама по себе помогает в любом случае, поэтому, если вы попробуете, обязательно сообщите о проблемах!

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

Я установил «календарь» времени потоковой передачи в нижней части моего канала Twitch . Я знаю, что если у кого-то есть учетная запись Twitch и они подписываются на меня, они будут получать уведомления, когда я выйду в эфир, но в остальном расписание - это то, где смотреть. Уверен, вы можете посмотреть, есть ли у вас учетная запись или нет. Я немного новичок в стриминге (делаю это всего пару недель), поэтому всегда открыт для лучших способов делать такие вещи. Несколько человек постоянно приходили ко мне и болтали / смотрели / болтали в чате, что очень весело :)

screen shot 2018-08-28 at 1 17 05 pm

Кей понял, приятно знать

и я обязательно опубликую вопросы, когда столкнусь с ними;)

Кстати, поскольку была упомянута Prism, я просто хотел бы добавить, что в идеале плагины для заметок / перефразирований должны использоваться напрямую, MDX поддерживает это с помощью параметров mdPlugins и hastPlugins (это может быть передано через gatsby -mdx). Плагины, такие как @ mapbox / rehype-prism, могут быть добавлены в hastPlugins , но были некоторые проблемы с пробелами, которые я исправил в mdx-js / mdx # 226, поэтому, как только они будут объединены и выпущены, подсветка синтаксиса будет хорошей идти!

да, полностью. gatsby-mdx уже поддерживает передачу плагинов реплики / повторения в ядро ​​mdx. Вот, например, @ mapbox / rehype-prism (я взял этот пример из некоторых ваших обсуждений PR / Issue, первоначально @silvenon , спасибо). AFAIK rehype prism не поддерживает плагины prism, поэтому это всегда компромисс в зависимости от вариантов использования (я считаю, что использование плагинов rehype для призмы означает, что вам будет труднее интегрировать что-то вроде реакции-live , например)

gatsby-comment-prismjs и другие подключаемые модули gatsby-comment- * были выпущены сегодня в версии 0.1.1, так что теперь есть как минимум 3 варианта подсветки синтаксиса между компонентами rehype / репликации / реакции 😝

Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

mikestopcontinues picture mikestopcontinues  ·  3Комментарии

kalinchernev picture kalinchernev  ·  3Комментарии

ghost picture ghost  ·  3Комментарии

brandonmp picture brandonmp  ·  3Комментарии

theduke picture theduke  ·  3Комментарии