Разработвам редактор на 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 (spec. режим): Режимът, който да използвате. напр. javascript
  • output (функция или DOM възел) : Ако това е функция, тя ще бъде извикана за всеки токен с два аргумента, текста на токена и стиловия клас на токена (може да бъде null за нестилизирани токени). Ако това е DOM възел, токените ще бъдат преобразувани в span елементи, както в редактор, и вмъкнати във възела (чрез innerHTML).

Третият аргумент приема функция, която ви позволява да генерирате виртуални DOM от текст! Това е добра новина. Можете да направите React компонент с помощта на runMode по този начин:

След това можете да го използвате, както следва:

Това работи чудесно. Направих обикновена библиотека с някои функции, които биха я направили по-удобна за използване във вашите React приложения, като theme prop. Тази библиотека се използва в Inkdrop сега :D

Надявам се тази статия да е полезна!

  • craftzdog/react-codemirror-runmode — Осветяване на синтаксиса за реакция, използвайки анализатора на CodeMirror
  • lowlight — Виртуално подчертаване на синтаксис за виртуални DOM и не-HTML неща