История создания Editor.js — модульного визуального редактора от команды студентов CodeX

На его основе работает редактор vc.ru, TJ и DTF.

Три с половиной года разработки, 24 репозитория, 500 закрытых пулл-реквестов и бессчётное число коммитов — большой opensource-проект готов к выходу из беты.

Если быть точным, это вторая версия проекта, в которой мы решили изменить название редактора с CodeX Editor на Editor.js, попутно переписав его с нуля. В статье я расскажу о пути, который прошла команда от первых набросков до релиза на Product Hunt.

История создания Editor.js — модульного визуального редактора от команды студентов CodeX

CodeX

Осенью 2015 года состоялась первая встреча клуба веб-разработки: студенты и молодые разработчики сформировали команду энтузиастов для изучения новых технологий, экспериментов и исследований. На второй встрече, вместе с запуском сайта, нам понадобился визуальный редактор, в котором мы могли бы писать статьи о своих экспериментах. В тот же вечер в репозиторий CodeX Editor был отправлен первый коммит.

Сегодня CodeX — это по-прежнему небольшая команда, но с большой (97 репозиториев!) инфраструктурой собственных opensource-библиотек и микросервисов, интегрированных друг с другом. А CodeX Editor 2.0 или Editor.js — один из наших крупнейших и основных проектов.

О редакторе

Основная концепция — блочная структура и чистые данные в виде JSON на выходе. В отличие от большинства редакторов, где пользователь работает с текстом внутри одной редактируемой обертки, в Editor.js каждый структурный элемент статьи — блок — это отдельный редактируемый элемент.

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

После сохранения редактор возвращает данные о каждом блоке.

{ "time" : 1550476186479, "blocks" : [ { "type" : "paragraph", "data" : { "text" : "The example of text that was written in Editor.js" } }, { "type" : "header", "data" : { "text" : "With the header of course", "level" : 2 } }, { "type" : "paragraph", "data" : { "text" : "So what do we have?" } } ], "version" : "2.8.1" }

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

Именно простота API и стала самой сложной и самой удачной идеей.

Первая версия

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

В качестве образцов блоков мы написали первые плагины: «Параграф», «Заголовок», «Картинка», «Список» и еще некоторые. Старались придумать примеры разных сценариев: от простого набора и оформления текста до плагинов, взаимодействующих с серверной частью. Это позволило развивать API, который даёт возможность создать абсолютно любой плагин.

Например, плагин Twitter по вставленной в текст ссылке должен был формировать виджет твита. Для этого на страницу надо предварительно подключить Twitter SDK — так в API появился метод 'prepare'. При инициализации редактор собирает prepare всех плагинов, запускает их и дожидается завершения перед отрисовкой интерфейса.

Осенью 2016 года мы внедрили первую версию на наш сайт, а также в контент-сервис CodeX Media. Примерно в это же время в «Комитете» началась разработка новой модульной платформы для изданий Osnova — и в качестве редактора выбрали CodeX Editor.

История создания Editor.js — модульного визуального редактора от команды студентов CodeX

Форк Paragraph

В «Комитете» на всех платформах развиваются мощные UGC-сообщества. Каждый пользователь может написать и опубликовать материал, а одна из задач платформы — снизить шансы на то, что вёрстка будет некачественная и некрасивая.

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

Помимо этого, JSON-структура позволяет легко извлекать нужные данные из материала. Например, можно получить первый блок с картинкой и использовать его как обложку для соцсетей в meta-информации. Или получить первый текстовый блок и выводить его в ленте.

Опять же за счет блочной структуры, материалы можно верстать отдельно для веба и мобильных приложений, для Instant Articles, Google AMP и даже озвучивать голосом.

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

Чтобы разграничить зоны ответственности, мы создали приватный форк CodeX Editor, получивший название Paragraph. Он решает задачи платформы, развиваясь, совершенствуя дизайн и повышая стабильность. Основной упор сделали на разработку новых плагинов и совершенствование имеющихся.

На сегодняшний день разработка Editor.js и Paragraph ведется параллельно.

Вторая версия

Лето 2017 года. Мы в CodeX решили устроить ивент: снять на неделю коттедж в лесу на берегу озера и днями и ночами работать плечом к плечу, осваивая новую область технологий: AR.

История создания Editor.js — модульного визуального редактора от команды студентов CodeX

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

К тому времени кодовая база одного только ядра Editor.js уже насчитывала более десяти модулей и десятки тысяч строк кода — подступило время рефакторинга, пересмотра архитектуры и реализации когда-то придуманных концептов.

История создания Editor.js — модульного визуального редактора от команды студентов CodeX

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

  • Появилась возможность инициировать несколько редакторов на странице параллельно.
  • Полностью обновлен и проработан API: убраны избыточные методы, названия и структура стали более логичными, появились новые возможности. Обратной совместимостью решили пожертвовать — слишком уж хорош получался новый интерфейс, а клиентов, кроме нас самих, к тому времени практически не было, ведь проект нигде не анонсировался.
  • Появился API для разработки не только плагинов для блоков, но и инструментов форматирования — выделения фрагментов текстов маркером, вставки инлайнового кода, ссылок и так далее.
  • Настройки блоков тоже стали плагинами: например, можно создать настройку «Спойлер», которая появится у всех блоков и будет сворачивать их содержимое.
  • Проект был полностью переписан на TypeScript. Это повысило надежность и улучшило структуру модулей.
  • Появилась подробная документация API и циклы гайдов по написанию плагинов.

На реализацию новых возможностей и переписывание кода ушел ни много ни мало год. И летом 2018 года мы анонсировали открытое бета-тестирование проекта.

Бета-тестирование

Запуск беты мы анонсировали в нашем небольшом паблике и Telegram-канале. Несмотря на малое число подписчиков, появились заинтересованные в продукте люди, и со временем их становилось все больше.

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

Это принесло свои результаты — в ходе тестирования многие моменты были улучшены, а на многие вещи удалось взглянуть со стороны. Где-то понадобилось улучшить документацию, а где-то изменить API.

Доработок и новых идей оказалось столько, что запланированный месяц тестирования вылился в пять. Где-то в середине мы поняли, что название CodeX Editor не самое удачное — большинство людей называли редактор просто CodeX. Домен editorjs.io оказался свободен.

Затянувшийся ремонт подошел к концу.

Релиз

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

Мы написали десятки гайдов и статей для разработчиков плагинов, сняли множество поясняющих GIF-анимаций, тщательно проработали документацию API, создали отдельную организацию на GitHub, в которой будут публиковаться лучшие плагины и дополнения.

За все время работы над проектом главным мотиватором каждого члена команды был предстоящий момент релиза. Под ним мы подразумевали публикацию проекта во всемирном хит-параде продуктов Product Hunt.

И сегодня этот день настал. Представляем вашему вниманию Editor.js 2.0 — новый редактор и новая большая opensource-история.

105105
29 комментариев

Отличный редактор !
А он открытый ? его в своих проектах юзать можно будет ?
(принцип тот же остался - на сервер типа массив параграфов уходить будет ?)
Спасибо !

5
Ответить

Привет!

Исходный код открыт и выложен на гитхабе :)
Вот тут можно найти ядро — https://github.com/codex-team/editor.js, а здесь наши плагины — https://github.com/editor-js

Ядро распространяем под лицензией Apache-2.0 (можно делать все, что угодно, упоминая оригинальную лицензию), плагины под MIT.

Формат данных и другие подробности есть в документации — https://editorjs.io

15
Ответить

Обожаю редакторы как на комитете, телеграфе, телетайпе и вордпрессе.ком (именно ком).

Крутая штука!

9
Ответить

Восхищаюсь вашей работой. Спасибо большое! Как пользователь ранее использовал другие предложения рынка, но теперь я точно знаю куда смотреть) На ханте апвот оставил.
Подскажите, пожалуйста, на вашем сайте https://editorjs.io/ вижу примечание связанное с видео, но в редакторе тестирую возможности и его не нахожу. Как добавить видео? А второй вопрос, возможно ли добавлять иной код, например плейлист с Я.музыка?

2
Ответить

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

Мы написали несколько для примера:
https://github.com/editor-js

У нас есть плагин Image, который поддерживает загрузку гифок и mp4, но требуется серверная имплементация

Есть плагин Embed, который позволяет вставлять YouTube, Vimeo и тд по ссылкам. Кстати, Яндекс.Музыку тоже поддерживает.

2
Ответить

Очень здорово! Этот мир нуждается в хороших WYSIWYG-редакторах :)
В сравнении с draft.js вы не стали пытаться работать с внутренним состоянием блока и просто оставили там html. Надо сказать, решение изящное (я в свое время не сработался с draft.js/slate.js — слишком много приходится кода вокруг писать, и результат не стабилен), но вдруг захочется большего? Например, есть ли возможность (или появится), сохранить в JSON блока дополнительные ключи с какими-либо данными и соответствует ли это философии проекта?
А можете вкратце написать, как вы работаете с состоянием (обновлением) редактора (понятно, что можно подсмотреть в коде), но хотелось бы ваш взгляд, почему сделали так, а не иначе. И проверяли ли на больших текстах (от 40 тыс. знаков)?
Наконец, вопрос про хранение в JSON. Если вы настраиваете поиск по тексту, насколько все усложняется? (логично хранить это в jsonb постгреса — подозреваю, что у вас так и есть)

Ответить

Именно из-за усложнения вывода таких данных и не стали пока применять отдельные структуры для форматирования инлайн-фрагментов. Внутренние споры об этом ведем до сих пор. Но наша изначальная задумка — максимально низкий порог входа для разработчиков. В будущих обновлениях, возможно, появится выбор.

Про дополнительные поля в JSON — прямо в точку. Уже проектируем такой уровень API. Нужен нам для плагина комментариев.

Про состояние, если совсем кратко, используем Proxy. То есть у нас по сути написан реактивный диспетчер блоков — добавили или изменили блок в массиве, он изменился в DOM.

Про хранение JSON планируем написать отдельную заметку в документации. У нас по разному везде. Тут, например jsonb. Elasticsearch легко интегрируется.

3
Ответить