Я разрабатываю редактор Markdown под названием Inkdrop, который обеспечивает красивую подсветку синтаксиса в блоках кода. Чтобы реализовать эту функцию, я проверил множество выделителей синтаксиса, но в итоге сделал еще один. Он отлично работает с React и не требует dangerouslySetInnerHTML
. Он поддерживает множество языков из коробки. Я хотел бы представить его, потому что это был бы небольшой совет для тех, у кого со мной схожие требования.
Две проблемы с CodeMirror и highlight.js
Редактор Markdown Inkdrop основан на CodeMirror, который представляет собой универсальный компонент текстового редактора, созданный для браузеров. Он предоставляет встроенную подсветку синтаксиса, поэтому пользователи могут редактировать текст в красивом интерфейсе. С другой стороны, Inkdrop использовал highlight.js для панели предварительного просмотра Markdown. Эта композиция отлично сработала, но с двумя проблемами.
Первая причина в том, что highlight.js не поддерживает некоторые языки, которые поддерживает CodeMirror (и наоборот). Иногда пользователей смущала эта разница между редактором и предварительным просмотром, и они думали: «Почему он не отображает Markdown одинаково?»
Во-вторых, для highlight.js и других подобных библиотек требуется функция рендеринга с использованием dangerouslySetInnerHTML
в React или просто ручное изменение DOM с помощью собственного javascript. Это не так эффективно, потому что при каждом изменении текста требуется полностью перестраивать DOM. Эту проблему можно решить с помощью lowlight - фантастической работы, проделанной Titus, который выводит виртуальные модели DOM и совместим с highlight.js. Это сработало отлично, но первая проблема все еще существовала.
Поэтому я решил сделать такое решение, как тусклый свет, но совместимое с CodeMirror.
CodeMirror как средство выделения синтаксиса
Я заметил, что CodeMirror предоставляет средство запуска режима, которое позволяет запускать его как средство выделения синтаксиса. Вы можете посмотреть демо здесь. CodeMirror.runMode
- это функция, которая принимает следующие аргументы:
text
(строка): документ, который нужно просмотреть с помощью маркера.mode
(спецификация режима): используемый режим. например,javascript
output
(функция или узел DOM): если это функция, она будет вызываться для каждого токена с двумя аргументами: текстом токена и классом стиля токена (может бытьnull
для токенов без стиля). Если это узел DOM, токены будут преобразованы вspan
элементы, как в редакторе, и вставлены в узел (черезinnerHTML
).
Третий аргумент принимает функцию, которая позволяет создавать виртуальные модели DOM из текста! Это хорошие новости. Вы можете создать компонент React, используя runMode
следующим образом:
Затем вы можете использовать его следующим образом:
Это прекрасно работает. Я сделал простую библиотеку с некоторыми функциями, которые сделали бы ее более удобной для использования в ваших приложениях React, например theme
prop. Эта библиотека сейчас используется в Inkdrop: D
Надеюсь, эта статья будет вам полезна!
- Craftzdog / react-codemirror-runmode - выделение синтаксиса для реакции с использованием парсера CodeMirror.
- Lowlight - Виртуальная подсветка синтаксиса для виртуальных DOM и не-HTML вещей.