— Pixels Commander

[ In English, На русском ]

Веб компоненты уже сегодня с React.js и ReactiveElements

В современной JavaScript разработке довольно остро стоит вопрос повторного использования кода и композиции проектов. Замечательным способом композиции является использование web-components, однако на текущий момент это требует большого количества полифилов, что снижает надежность и быстродействие. ReactiveElements предлагает использовать React.js для описания веб-компонент, избавиться от большинства полифилов и использовать реактивные веб-компоненты уже сегодня.

UPD: Вы можете создавать веб-компоненты из Backbone и Angular вью с помощью  MVC Elements

Существует много MVC фреймворков, каждый со своими преимуществами или недостатками. Общим недостатком является закрытость, невозможность совместного использования с другими. А что если у вас уже есть база компонент на одном из фреймворков, а на текущем проекте необходимо использовать новый? А что если для части проекта вам нужен другой подход нежели предлагает текущий, основной фреймворк?

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

Основа для веб-компонент — это возможность использовать пользовательские HTML теги. Содержимое и поведение таких тегов (веб-компонент) определяется их разработчиком. Это может быть тег <touch-galery> — галерея или тег <broadcast-list> — программа передач на ТВ.

Пользовательские теги — самый важный элемент веб-компонент, однако для полноценной работы недостаточно просто описать тип тега. Нужен удобный способ подключения тега в проект, загрузки его шаблона. Так же нужно быть уверенным, что тег является вещью в себе и при добавлении не изменяет соседние теги и содержимое страницы. Для этого в стандарт введены спецификации HTML import и Shadow DOM.

Итого веб — компоненты состоят из:

  • HTML templates;
  • Custom elements;
  • Shadow DOM;
  • HTML import.

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

Сильные стороны React:

  • React ориентирован на компонентную модель разработки;
  • «реактивность» создаваемого интерфейса, отсутствие ручных DOM манипуляций;
  • Наличие виртуального DOM дерева и оптимизация рендеринга;
  • Всем знакомые механизмы загрузки шаблонов через подключение JavaScript файлов.

Таким образом использование React решает проблему импорта компонент и делает ненужным HTML Import и HTML Template polyfill`ы. Так же нам больше не нужен Shadow DOM — React управляет своей DOM структурой самостоятельно и весьма эффективно.

Для использования React виджетов, как веб — компонент разработан небольшой враппер ReactiveElements. Для корректной работы он требует только поддержку custom element части спецификации. Это легко обеспечить подключив в проект Mozilla X-Tag, Google Polymer, а в последнее время Custom Element довольно часто присутствует в браузерах «из коробки».

На текущий момент и X-Tag и Google Polymer используют один и тот же Custom Element полифилл https://github.com/Polymer/CustomElements

Для создания реактивного элемента из React компонента достаточно просто выполнить:

document.registerReact('tag-name', reactClass);

Этот пример отображает простейший ReactiveElement а так же проводит возможные манипуляции с элементом — задает свойства через аттрибуты тега и напрямую через ссылку на HTML элемент, так же через ссылку выполняет методы React класса.

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

<body>
    <h1>Choose category</h1>
    <select onchange="changeCategory(value)">
        <option value="sport">Sport</option>
        <option value="documentary">Documentary</option>
        <option value="kids">Kids</option>
    </select>
    <broadcasts-list id="myBroadcastList" category="sport" region="IE"></broadcasts-list>
    <script>
        function changeCategory(value) {
            var myBroadcastList = document.getElementById('myBroadcastList');
            myBroadcastList.setAttribute('category', value);
            myBroadcastList.refreshData();
        }
    </script>
</body>

ReactiveElements на GitHub

UPD: Теперь вы можете создавать web-компоненты из Angular директив и Backbone views используя проект MVC Elements.

  • Jean Baro

    Sorry. But is this project dead? Congratulations for your wonderful work!

  • Аноним

    Thank you. No it is not. Still in development. On 25 of June will speak about ReactiveElements at Amsterdam JS MVC meetup http://www.meetup.com/JavaScript-MVC-Meetup-Amsterdam/events/182288022/?comment_table_id=183165142&comment_table_name=reply

    In fact idea of project is quite compact and there is not too much to add. If you have any feature requests — just let me know. I am interested in evolving this thing further.

  • Jean Baro

    Great to know. I am planing to use it on a toy project I’ll start in the coming weeks. I’ll feedback any issue or new feature required I find. Thanks

  • Daniel Wabyick

    I’m trying to use custom web components *within* React components. Naive attempts don’t work. Is this possible?

  • Аноним

    Could you drop a JSFiddle or smth? Since React supports limited list of tags there could be a pitfall doing this. But sure, we can make it.

  • Аноним

    Have you tried this with React v0.12 ? Should work fine after update.