Каковы сильные и слабые стороны реального мира многих фреймворков на основе backbone.js?

Надеюсь, что кто-то может поделиться своим опытом с некоторыми из последних новых вариантов backbone.js. У меня есть хороший опыт работы с базой/подчеркиванием/требованием в нескольких проектах, и я хотел бы сделать следующий шаг к более продвинутым решениям для сложной структуры приложения.

Я знаю, что доступны следующие рамки:

И, вероятно, я пропустил несколько.

Существует краткое введение о различиях здесь:

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

В чем преимущество выбора одного над другим? Когда марионетка станет лучшим решением для чаплина или, например, лучше для некоторых приложений, например.

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

Спасибо!

Изменить 1: нашел это сообщение: Backbone.Marionette vs Backbone-Boilerplate

Изменить 2: Ответа на этот вопрос Mathias schafer (Chaplin) по почте:

Короче говоря, текущая структура близка к версии 1.0, поскольку она уже используется в производстве. Не планировали добавлять новую новую функцию или изменять API до 1.0.

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

Напротив, Чаплин фокусируется на довольно небольшом, но очень важном аспекте приложений Backbone, а именно на общей структуре приложения и жизненном цикле модуля. В связи с этим Чаплин очень опирается и больше похож на структуру, чем на библиотеку (например, "ваш код вызывает библиотеку, каркас вызывает ваш код" ). Чаплин предоставляет некоторые центральные классы, которые располагаются над отдельными модулями приложений и контролируют общее состояние приложения. Это дает вашему приложению обычную структуру, например Ruby on Rails.

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

Есть два принципала, которые приходят вместе с этой структурой: - Модуляция, развязка и песочница - Межмодульная связь с использованием публикации/подписки и медиатора (ов)

Конечно, эти шаблоны не новы в мире разработки программного обеспечения, а Chaplin - не единственная библиотека, которая применяет их к приложениям Backbone.js.

Чаплин также предоставляет улучшения для слоя "Вид", например, очень сложный CollectionView, но в целом не так много, как Marionette с его областями и макетами. Но относительно легко писать такие мета-классы, используя средства Chaplin Views.

Ответ 1

Большинство (всех?) фреймворков, которые вы ищете для решения одних и тех же проблем, но они делают это несколько иначе, с несколько разными целями.

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

  • Обеспечить разумный набор значений по умолчанию
  • Уменьшить шаблонный код
  • Предоставление структуры приложения поверх строительных блоков BackboneJS
  • Извлечь шаблоны, которые авторы используют в своих приложениях

Marionette, с которой я строилась с декабря 2011 года, имеет в виду несколько очень разных целей и идеалов:

  • Архитектура составного приложения
  • Влияние шаблона обмена сообщениями в организации
  • Параметры модуляции
  • Инкрементное использование (без требования "все или ничего" )
  • Нет блокировки сервера
  • Легко изменить эти значения по умолчанию
  • Код как конфигурация/конфигурация

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

Архитектура составного приложения

Я провел более 5 лет, работая в толстых клиентских распределенных программных системах с использованием WinForms и С#. Я создал приложения для настольных компьютеров, ноутбуков (smart-client), мобильных устройств и веб-приложений, все из которых имеют общий функциональный набор и работают с одним и тем же сервером. За это время я узнал стоимость модуляции и очень быстро продвинулся по пути разработки композитного приложения.

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

Я написал немного об этом в своем блоге, представляя Marionette как составную архитектуру приложений для Backbone:

Очереди сообщений/шаблоны

Те же широкомасштабные распределенные системы также использовали преимущества очереди сообщений, шаблонов корпоративной интеграции (шаблонов обмена сообщениями) и служебных шин для обработки сообщений. Это больше всего на свете оказало огромное влияние на мой подход к развязанной разработке программного обеспечения. С этой точки зрения я начал рассматривать однопроцессорные приложения с поддержкой WinForms, и вскоре из этого повлияло развитие моего сервера и веб-приложений.

Это непосредственно перешло к тому, как я смотрю на дизайн приложения Backbone. Я предоставляю агрегатор событий в Marionette, как для объекта приложения высокого уровня, так и для каждого модуля, созданного в приложении.

Я думаю о сообщениях, которые я могу отправлять между моими модулями: командные сообщения, сообщения о событиях и многое другое. Я также думаю о связи на стороне сервера как сообщения с этими же шаблонами. Некоторые из шаблонов уже вошли в "Марионетт", но некоторые еще не сделали этого.

Модульность

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

Marionette обеспечивает модуляцию непосредственно через это определение module. Но я также признаю, что некоторые люди, такие как RequireJS, и хотят использовать это. Поэтому я предоставляю как стандартную сборку, так и сборку RequireJS.


MyApp = new Backbone.Marionette.Application();

MyApp.module("MyModule", function(MyModule, MyApp, Backbone, Marionette, $, _){

  // your module code goes here

});

(Пока нет сообщений в блоге)

Инкрементальное использование

Это одна из основных философий, которую я запекаю в каждую часть Марионетты, которую я могу: нет требования "все или ничего" для использования Marionette.

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

С этой целью большинство кусков, которые я построил в Marionette, построены на одиночку, чтобы работать с основными частями Backbone и работать вместе еще лучше.

Например, почти каждое приложение Backbone должно динамически отображать представление Backbone в определенном месте на экране. Приложения также должны обрабатывать закрытие старых представлений и очистку памяти при установке нового. Здесь играет Марионетка Region. Область обрабатывает шаблонный код для просмотра, вызывая визуализацию на нем и набивая результат в DOM для вас. Затем закроет это представление и очистит его для вас, если на вашем представлении есть "близкий" метод.


MyApp.addRegions({
  someRegion: "#some-div"
});

MyApp.someRegion.show(new MyView());

Но вы не обязаны использовать представления Marionette, чтобы использовать регион. Единственное требование состоит в том, что вы расширяетесь от Backbone.View в какой-то момент в цепочке прототипов объекта. Если вы решите предоставить метод close, метод onShow или другие, регион Марионет вызовет его для вас в нужное время.

Нет блокировки сервера

Я создаю приложения Backbone/Marionette поверх широкого спектра серверных технологий:

  • ASP.NET MVC
  • Ruby on Rails
  • Ruby/Sinatra
  • NodeJS/ExpressJS
  • PHP/Slim
  • Java
  • Erlang
  • ... и многое другое

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

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

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

Легко изменить настройки по умолчанию

В моих усилиях по сокращению кода шаблона и обеспечению разумных значений по умолчанию (это идея, которую я непосредственно "заимствовал" у Tim Branyen LayoutManager), я признаю необходимость того, чтобы другие разработчики использовали несколько разные реализации, чем я.

Я предоставляю рендеринг на основе встроенных тегов <script> для шаблонов, используя шаблон Underscore.js по умолчанию. Но вы можете заменить это, изменив объекты Renderer и/или TempalteCache в Marionette. Эти два объекта обеспечивают ядро ​​возможностей рендеринга, а также есть страницы вики, в которых показано, как изменить это для определенных механизмов шаблонов и различные способы загрузки шаблонов.

С v0.9 Marionette это становится еще проще. Например, если вы хотите заменить использование встроенных шаблонов script блоками с предварительно скомпилированными шаблонами, вам нужно только заменить один метод на Renderer:


Backbone.Marionette.Renderer.render = function(template, data){
  return template(data);
};

и теперь все приложение будет использовать предварительно скомпилированные шаблоны, которые вы прикрепляете к вашему представлению template.

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

Код как конфигурация

Я поклонник "конвенции по конфигурации" в определенных контекстах. Это мощный способ добиться успеха, и Marionette предоставляет немного этого - хотя и не слишком, честно. Многие другие структуры, особенно LayoutManager, обеспечивают более условную конфигурацию, чем Marionette.

Это делается с целями и намерениями.

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

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

Предоставляя чистый и понятный API для объектов Marionette, я создаю ситуацию, когда замена поведения конкретного объекта или Marionette в целом относительно проста и очень гибкая. Я жертвую "простыми" API-интерфейсами конфигурации для гибкости предоставления собственного кода, чтобы заставить работу работать так, как вы хотите.

Вы не найдете API-интерфейс "configure" или "options" в Marionette. Но вы найдете множество методов, каждый из которых будет служить очень конкретной цели, с чистыми подписями, которые облегчат изменение работы Marionette.

Ответ 2

В настоящее время я использую магистраль с модулем диспетчера компоновки и ручками в качестве шаблонов для моделирования, и мне было очень легко настроить небольшое приложение, используя уже существующий сервер Grails. Прежде чем начать использовать менеджер компоновки, я читал о Марионете и Чаплине, и оба казались мне очень мощными, но сложными. Затем я вспомнил, почему я изначально выбрал backbone.js: простота. Все эти фреймворки добавляют то, что позволено оставить в дизайне. Я не говорю, что фреймворк плох, но если мне нужно что-то более сложное, я попробую другие проекты, такие как ember.js или sproutcore, поскольку у них есть уникальная кодовая база, написанная с целью в сознании их разработчиков. Здесь у нас есть рамки поверх другого. Конечно, позвоночник является основой не только для создания приложений, но и для написания более мощной библиотеки, но единственное, что, по моему мнению, очень плохое, - это уровень представления, поскольку отсутствует менеджер компоновки и возможность просмотра вложенности, С менеджером компоновки этот пробел заполнен достаточно хорошо.

Итак, мой ответ на ваш вопрос: начните с использования магистрали, как есть, и спросите себя, чего не хватает, и каковы были ваши ожидания относительно структуры. Если вы обнаружите, что слишком много вещей, оставшихся вне позвоночника, затем перейдите и найдите их в других рамках и выберите тот, который вам больше всего подходит. И если вы все еще не уверены в выборе, возможно, магистраль не для вас, и вам нужно искать какое-то другое решение (ember.js, sproutcore, ExtJs, JavaScript MVC - все хорошо). Если у вас есть опыт написания клиентских приложений, вам действительно не нужен опыт во всех рамках, чтобы выбрать правильный (для вас, конечно)

Ответ 3

Я изучил различные структуры с помощью Backbone.js и построил Vertebrae для проекта в HauteLook. Цели проекта включали... динамическую загрузку, формат модуля AMD, управление зависимостями, сборку с использованием в основном библиотек с открытым исходным кодом, организацию кода в пакетах, оптимизацию и сборку для одного или нескольких приложений с одной страницей, размещение на полностью кэшированном сервере, например. нет сценариев на стороне сервера, использующих только API для данных, и самое смешное для меня, используйте разработку, ориентированную на поведение для проекта. Описание проекта: http://www.hautelooktech.com/2012/05/24/vertebrae-front-end-framework-built-with-backbone-js-and-requirejs-using-amd/

Наша проблема:

Выбранные библиотеки (jQuery, Underscore.js, Backbone.js, RequireJS, Mustache) обеспечивают загрузку модулей, управление зависимостями, структуру приложения (для моделей, коллекций, представлений и маршрутов), асинхронные взаимодействия с API, различные утилиты и объекты для управлять асинхронным поведением, например (Promises) Отсрочка, обратные вызовы. Оставшаяся логика, необходимая для завершения структуры, включает в себя:

  • объект (модель) для управления состоянием одностраничного приложения;
  • менеджер компоновки для представления, упорядочения/перехода и очистки просмотров и
  • которые отвечают на маршруты, получают/устанавливают состояние приложения и отдают работу менеджеру макетов.

Наши решения (реализованы в Vertebrae):

Диспетчер состояний приложения -

Диспетчер приложений хранит данные в памяти, а также сохраняет данные в хранилище браузера для предоставления ресурсов для общих данных/метаданных. Также предоставляет данные (состояние) для восстановления просмотров страниц на основе предыдущих взаимодействий (например, выбранная вкладка, применяемые фильтры). Диспетчер состояний приложения предоставляет стратегию для ресурсов для извлечения состояния. Предназначен для работы в качестве конечного автомата.

Менеджер макетов -

Менеджер компоновки имеет одно или несколько представлений, а также адресатов документа (DOM) для каждого (визуализированного) представления. Страница может переходить между многими представлениями, поэтому менеджер компоновки отслеживает состояния просмотра, например. визуализируется, не отображается, отображается, не отображается. Вы можете использовать диспетчер компоновки для ленивых загрузочных и рендеринговых (просмотренных) представлений, которые, скорее всего, запрашивает посетитель сайта, например. вкладки на странице. Этот объект управляется переходом между состояниями представления. Весь макет может быть очищен, так что объекты просмотра и их привязки удаляются, подготовка этих объектов для сбора мусора (предотвращение утечек памяти). Менеджер компоновки также передает состояние просмотра с контроллерами.

Контроллер -

Объект контроллера вызывается функцией обработчика маршрута и отвечает за получение соответствующего состояния (моделей приложений) для создания страницы (макета) (также отвечает за настройку состояния при изменении маршрутов). Контроллер передает зависимые данные (модели/коллекции) и создает объекты просмотра для запрашиваемой страницы в менеджере компоновки. В качестве побочного эффекта использование контроллеров предотвращает раздувание и запутывание объекта маршрута. Маршрут должен сопоставляться с контроллером, который затем запускает просмотр страницы, сохраняя функции обработки маршрута.

Приложение Todos размещено как в режиме dev, так и оптимизировано на Heroku...

Многие из концепций в других рамках заимствованы, например. необходимость уничтожить представления для предварительного просмотра утечек памяти, как указал Дерик Бейли - http://lostechies.com/derickbailey/; Менеджер макета Тима Браниена http://tbranyen.github.com/backbone.layoutmanager/

В заключение, Backbone.js предназначен для использования в вашем приложении, библиотека Backbone.js не предоставляет всю архитектуру, необходимую для создания приложения, но обеспечивает отличные взаимодействия с API и сплошной структурой кода для... Представления (действуют как контроллеры) и ваши модели и коллекции данных, и, наконец, маршруты. Мы построили Vertebrae для мяса цели нашего проекта и решили извлечь код в качестве основы для других, чтобы использовать, учиться или что угодно.

Ответ на ваш вопрос, на мой взгляд, заключается в том, чтобы узнать из всех фреймворков и использовать то, что вам нужно для достижения ваших целей, если вы обнаружите, что ваши цели проекта тесно связаны с одной из структур, построенных с помощью Backbone, тогда великолепно, иначе построены в вашей собственной структуре есть отличные примеры, которыми обменивается сообщество. Или, если вы немного потеряли в сторону своего приложения, то выберите что-то более упрямое и структурированное, возможно, Ember.js. Самое замечательное в том, что есть хороший выбор вариантов, которые помогут вам с помощью MVV-шаблона MVQ с JavaScript.

Ответ 4

Я разработал структуру Luca, работая в BenchPrep, где мы использовали его для разработки нескольких крупных приложений с одной страницей поверх библиотеки backbone.js.

Я работал с ExtJS несколько лет назад и украл мои любимые концепции из этой структуры, такие как архитектура с компонентами, где вы разрабатываете свои представления как автономные компоненты, а затем объединяете их вместе с другими компонентами, используя представления контейнеров. И поскольку он в значительной степени основан на конфигурации, разработка приложения в Luca очень похожа на описание объекта с JSON.

Одним из преимуществ такого подхода является возможность повторного использования компонентов в нескольких приложениях или в разных местах вашего приложения с незначительными изменениями с использованием Backbone. Также очень легко поэкспериментировать со многими различными макетами/презентациями компонентов, делая лишь незначительные изменения в конфигурации JSON.

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

Представления, компоненты, контейнеры

  • Расширенные модели, просмотр, сбор, классы маршрутизаторов
  • Параметры конфигурации, которые облегчают обмен данными между моделями, коллекциями, представлениями, приложением и соответствующими менеджерами.
  • Контейнеры (разметка/расположение столбцов, макет сетки, вкладка, вид карты/мастера)
  • FormView со всеми стандартными компонентами поля и помощниками для синхронизации с Backbone.Model
  • GridView для генерации прокручиваемых элементов сетки из Luca.Collection
  • CollectionView, для создания представлений на основе коллекции
  • Панели инструментов/Кнопки

Щебетать стили бутстрапа и разметку бесплатно

  • Luca очень хорошо играет в платформе Twitter-загрузки. Просто установив Luca.enableBootstrap = true и включив CSS, ваши компоненты (такие как представления вкладок, панели инструментов, кнопки, формы, поля, сетки и т.д.) Будут автоматически использовать разметку, совместимую с Twitter Bootstrap и CSS.
  • Использует систему Grid для компоновки и отвечает на большинство базовых классов css bootstrap интеллектуальным способом.
  • Компоненты Luca.Viewport и GridLayout настроены для работы с загрузочными, жидкостными или статическими сетными системами с бутстрапом.
  • Цель состоит в том, чтобы обеспечить индивидуальное соответствие для компонентов twitter bootstrap, чтобы представлять их как настраиваемые представления Backbone.

Компонент приложения

  • Базовый автомат на основе базы данных предоставляет методы getter/setter и события изменения атрибутов как стиль потока управления приложениями.
  • Компонент Integrated Controller, который скрывает/показывает страницы приложения в ответ на события Backbone.Router или State Machine
  • Integrated Collection Manager, который отслеживает созданные вами коллекции, позволяет вам их охватить, группировать, присваивать им параметры по умолчанию
  • Socket Manager, который является абстракционным слоем поверх сервисов websocket, который делает push так же просто, как Backbone.Event
  • Маршрутизатор событий на клавиатуре, который запускает ключевые события на компонентах, которые хотят реагировать на такие события.

Улучшения коллекции и моделей

  • Коллекции основаны на backbone-query, который предоставляет интерфейс запросов, очень похожий на mongoDb
  • включить локальное хранилище Backbone.sync, просто установив collection.localStorage = true
  • автоматическая совокупность коллекций, данные которых загружаются при загрузке страницы
  • кэшированные методы/вычисленные свойства. кэшировать результат методов сбора и истекать кеш в ответ на изменение/добавление/удаление событий в коллекции или ее моделях.
  • вычисленные свойства на моделях. строить атрибуты на основе сложной функции и автоматически обновлять вычисленное значение в ответ на изменения

События и крючки

Компоненты Luca более либеральны с событиями, которые они излучают, по сравнению с компонентами базовой линии. Они будут генерировать такие события, как раньше: initialize, after: initialize, before: render, after: render, activation, first: активация, деактивация, сначала: деактивация, и это позволяет более точно настраивать поведение ваших компонентов. Кроме того, определив событие в стиле @hooks на вашем представлении, он автоматически вызовет аналогичную именованную функцию для вас, если она существует. Это предотвращает много кода стиля обратного вызова, что улучшает читаемость.

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

Ruby Gem

Luca был разработан специально при работе с Rails и Sinatra API, и из-за этого в настоящее время оптимизирован для определенного стека, но он никоим образом не блокирует вас на конкретном сервере.

Luca поставляется в составе Ruby Gem, настроенного для работы с конвейером активов или в виде загружаемого JS файла.

Вы не обязаны использовать Rails или Sinatra. Но если вы это сделаете, я включил много полезных вещей:

  • Файлы с расширением .luca обрабатываются как HAML с интерполяцией переменных стиля JST. (эквивалент .jst.ejs.haml) по конвейеру активов
  • Испытательная проводка для браузеров или безголонных тестов на основе жасмина, а также много тестовых помощников Backbone и Underscore.
  • Конечная точка API для набора инструментов разработки, который поставляется с Luca (подробнее об этом позже)
  • Конечная точка API, которая позволяет использовать Redis в качестве механизма хранения без кода для Luca.Collection с минимальной конфигурацией

Средства разработки

  • Приложения Luca могут включать консоль браузера coffeescript с конкретными помощниками и командами Luca, которые помогают контролировать, проверять, отлаживать приложения и компоненты Luca.

An example of the Luca in browser Development Console powered by CoffeeScript

  • С помощью редактора Rails Gem и Luca CodeMirror вы можете отредактировать исходный код Luca Framework, а также конкретных компонентов приложения непосредственно в браузере, используя Coffeescript. Вы увидите немедленную обратную связь в ответ на ваши изменения, когда экземпляры обновленных объектов обновляются обновленным прототипом, и вы можете сохранить свои изменения на диске.

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

  • Компонентный тестер скоро интегрируется с Jasmine, чтобы вы могли просматривать результаты ваших тестов компонентов в реальном времени при редактировании их кода

A screenshot of the component tester

Luca - это работа, но она поддерживает стабильный API (еще не 1,0) и используется в нескольких крупных производственных приложениях. Это определенно очень упрямая структура, но я работаю над тем, чтобы сделать ее более модульной. Я активно работаю над документацией и примерами компонентов.