Понятно и просто про WEB-компоненты и Polymer

от автора

Кто я

Я — Александр Кашеверов. По образованию — магистр радиофизики. По профессии — веб-разработчик, работаю в компании DataArt с 2011 года, с 2009 увлекаюсь IT и веб-технологиями.

О чем статья, коротко

Рассмотрим, что такое web-components и polymer. Немного поразмышляем на тему развития веба. Посмотрим на технические детали, примеры, поддержку браузерами, тестирование. Коротко, понятно, по делу. С картинками.

Вступление

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

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

Для уменьшения головной боли хорошо бы, если в контексте веб:

  • CSS не пересекался.
  • Области видимости JS не пересекались.
  • HTML был понятным и читаемым, никаких лишних элементов.


В настоящее время это не совсем так. Относительно JavaScript: приходится следить, чтобы он не работал с global scope и разные компоненты случайно не взаимодействовали друг с другом. В CSS нет и не было инкапсуляции, приходится придумывать методологии вроде MCSS и bem, чтобы ничего лишний раз не сломалось. И наконец, в HTML можно увидеть множество лишних элементов на странице, например, даже сейчас в почте gmail…

Запутанно… Не правда ли?
Фреймворки в той или иной степени внедряют компонентизацию и стараются решить эти задачи. Однако, они так же построены на всё тех же HTML, CSS, JavaScript.

Web Components — коротко

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

История веб-компонентов началась в 2011 году (первое упоминание на github). Кратко — что это:

  • Custom Elements — создание своих html-элементов, дополнение существующих.
  • Shadow DOM — инкапсуляция логики и стилей.
  • Templates — шаблоны на уровне браузера!
  • HTML imports — вместо подключения отдельно разных файлов [css, js, …] можно подключать один HTML-документ, включающий все остальные файлы.

При использовании этих четырех технологий вместе, получаются автономные пеереиспользуемые блоки — веб-компоненты.

На самом деле, некое подобие веб-компонентов уже было создано давно. Простейший пример — элемент <select> . Для него есть отдельный тег. Взаимодействуя с элементом, появляется выпадающий список и эта логика скрыта от нас, к тому же у него есть свои собственные стили.

<select>    <option value="Yandex">Yandex</option>    <option value="Google" selected>Google</option>    <option value="Yahoo">Yahoo</option> </select> 

Так же и с HTML5 элементами <video> или <audio> .

В этом и есть суть web-компонентов — создание простых и понятных независимых элементов со скрытой логикой, стилями.

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

<link rel="import" href="bootstrap.html"> 

Web Components — не фреймворк. Это набор технологий, реализованных на уровне браузера.

Web Components — поддержка браузерами & polyfills

На данный момент (ноябрь 2015) три из чеырех технологий находятся в стадии «Working Draft» на W3C.
Так выглядит ситуация на данный момент (ноябрь 2015):

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

С их помощью, поддержка браузерами уже получше.

На web-странце, полифиллы подключается стандартно в head (до всех скриптов, которые используют веб-компоненты):

<script src="path/webcomponents.js"></script> 
Web Components — ссылки

Polymer

Тем временем, Google всё упрощает и развивает. Работа началась осенью 2012 года, судя по истории коммитов на github. Они взяли веб-компоненты, полифилы и создали еще одну надстройку.

Цель Polymer — упростить создание качественных веб-приложений (цитата product manager с конференции Google IO).

Polymer — коротко

Библиотека представляет собой веб-компоненты в основе, полифилы для поддержки старых браузеров, это всё обернуто в целостную более удобную систему с добавлением сахара.

Сехматически это выглядит так:

Google создал набор готовых компонент и разделил их на логические части:
 

Основные строительные блоки <iron-icon>, <iron-input>, <iron-list>, …
Элементы на основе iron-elements и material design <paper-input>, <paper-button>, <paper-tooltip>, …
Коллекция web-компонентов, использующих различные API Google <google-analytics>, <google-chart>, <google-map>, …
Элементы, специфичные для интернет-коммерции <gold-cc-input>, <gold-phone-input>, <gold-email-input>, …
Элементы для создания анимаций <neon-animation>
Элементы, помогающие создать из веб-страницы настоящее приложение <platinum-bluetooth-device>, <platinum-sw-cache>, <platinum-push-messaging>, …
Элементы-обертки других библиотек/приложений <marked-element>

 

Можно заметить, что постоянно фигурирует слово «элемент». Google считает, что для всего можно сделать элемент. «There is an element for that» («для этого есть элемент») — звучит, как слоган в докладах Google IO 2015.

Да, даже для ajax запроса есть элемент. Выглядит так:

<iron-ajax url="some url" handle-as="json" on-response="onResponse"></iron-ajax> 

При создании приложений мы сталкиваемся с примерно одинаковыми задачами, и Google предлагает набор готовых строительных блоков для этого. С какой бы проблемой мы не столкнулись — для ее решения есть элемент. «There is an element for that».
Создан каталог готовых Polymer-компонентов.

Polymer — не фреймворк, как и Web Components — не фреймворк. Polymer — это обертка и сахар. Я бы идейно ее сравнил с jQuery. jQuery создана для работы с DOM, а Polymer — для работы с Web Components.

Polymer — тестируемость

Да, он тестируемый, и для этого создана отдельная утилита web-component-tester. Понятное описание.

Пробовал. Работает (при установке могут возникнуть проблемы с Java и Selenium).

Несколько шагов, чтобы заработало:

  • Установить
    npm install -g web-component-tester 

    Написать тест, просто html файл (по-умолчанию, в папке `./test`):

    <!doctype html> <html> <head>   <meta charset="utf-8">   <script src="path/webcomponentsjs/webcomponents.min.js"></script>   <script src="path/web-component-tester/browser.js"></script>   <link rel="import" href="path/awesome-element.html"> </head> <body>   <awesome-element id="fixture"></awesome-element>   <script>    suite('<awesome-element>', function() {       test('is awesomest', function() {         assert.isTrue(document.getElementById('fixture').awesomest);       });     });   </script> </body> </html> 

    Запустить тесты:

    wct 
    Polymer — поддержка браузерами

    Polymer — сахар веб-компонента, поэтому и поддержка браузерами точно такая же. Таблицы были представлены выше.

    К слову, у меня так и не получилось запустить на старом Android-телефоне.

    Polymer — оптимизация vulcanize

    HTML imports позволяет быстро и удобно подключить документ в другой документ, но в этом удобстве скрывается и проблема производительности: создается множество http-запросов. Решение есть —- соединить все подключаемые файлы в один. Для этого служит утилита vulcanize.

    Установка:

    npm install -g vulcanize 

    Использование:

    vulcanize index.html > build.html 
    Polymer — starter kit

    Для удобства быстрого создания проектов есть утилита Polymer Starter Kit. После установки сразу доступно множество полезной функциональности.
    Собрано в коробку:

    • Polymer-, Paper-, Iron- и Neon-элементы.
    • Material Design-верстка.
    • Роутинг с Page.js.
    • Юнит тесты с помощью Web Component Tester.
    • Поддержка оффлайн-работы с помощью Platinum Service Worker.
    • Создание билда (включая Vulcanize).
    • ES2015-поддержка.
    Polymer — альтернативы

    Polymer — лишь надстройка над Web Components. Есть и другие подобные продукты:

    Polymer — ссылки

    Polymer — про взаимодействие с библиотеками

    • Angular 2
    • Веб-компоненты будут внедрены в Angular 2: angularjs.blogspot.ru (eng).
    • React
      Официальный представитель от React Sebastian Markbage говорит, что они не будут использовать Web Components совместно с React, т. к. они идеологически разные (декларативный React против императивных Web Components): docs.google.com (eng). Однако, React и Web Components совместимы, в некоторых случаях есть польза: youtube.com (eng).
    • Backbone
      Удобно скрестить с уже готовыми компонентами (Polymer, X-Tags, Bosonic). Используются точно так же, как обычные HTML-элементы. webcomponents.org (eng).
    Web-components & Polymer — примеры

    Рассмотрим простой пример веб-компонента и его Polymer-реализацию:

    Пример чистого веб-компонента:

    <template>     <span id="multiplier"></span> * <span id="multiplicand"></span> = <span id="result"></span> </template>  <script>      (function(window, document) {         var ownerDocument =  (document._currentScript || document.currentScript).ownerDocument;         var template = ownerDocument.querySelector('template').content;         var elementPrototype = Object.create(HTMLElement.prototype);         var multiplier = 0, multiplicand = 0, result = 0;         elementPrototype.createdCallback = function() {             var shadowRoot = this.createShadowRoot();             var clone = document.importNode(template, true);             shadowRoot.appendChild(clone);             this.multiplier = shadowRoot.querySelector('#multiplier');             this.multiplicand = shadowRoot.querySelector('#multiplicand');             this.result = shadowRoot.querySelector('#result');             this.calculate();         };          elementPrototype.attributeChangedCallback = function(attr, oldVal, newVal) {             this.calculate();         };          elementPrototype.calculate = function(){             multiplier = parseFloat( this.getAttribute('multiplier') );             multiplicand = parseFloat( this.getAttribute('multiplicand') );             this.multiplier.textContent = multiplier;             this.multiplicand.textContent = multiplicand;             this.result.textContent = multiplicand*multiplier;         };         window.MyElement = document.registerElement('element-multiplier', {prototype: elementPrototype });     })(window, document);  </script> 

    Подключаем в <head> -> <link rel="import" href="element-multiplier.html">
    Используем на странице (в <body> ) -> <element-multiplier multiplier="3" multiplicand="2"></element-multiplier>

    С Polymer будет выглядеть заметно понятней и проще:

    <link rel="import" href="polymer.html">  <dom-module id="element-multiplier">     <template>         <span>{{multiplier}}</span> * <span>{{multiplicand}}</span> = <span>{{result}}</span>     </template> </dom-module>  <script>     Polymer({         is: "element-multiplier",         properties: {             "multiplier"    : { type: Number, value: 0, observer: 'calculate' },             "multiplicand"  : { type: Number, value: 0, observer: 'calculate' },             "result"        : { type: Number, value: 0 }         },         ready: this.calculate,         calculate: function(){             this.result = this.multiplier*this.multiplicand;         }     }); </script> 

    Подключаем в <head> -> <link rel="import" href="path/element-multiplier.html"><script src="path/webcomponents.min.js"></script>
    Используем на странице (в <body> ) -> <element-multiplier multiplier="3" multiplicand="2"></element-multiplier>

    Примеры:

    • pubnub.com — (eng) создание приложения на Polymer.
    • translate.google.com — создан на Polymer.
    • todomvc.com — (eng) пример TODO MVC на Polymer.
    • pubnub.github.io — (eng) анонимный чат на Polymer.
    • github.com — (eng) мое маленькое приложение. Идея проста: когда группа людей делает совместную покупку с одинаковыми вкладами, часто возникает путаница в расчетах долгов, когда скидываются не все сразу. Писал специально, чтобы попробовать Polymer. Там настроены тесты и vulcanize, реализована минификация JS в один файл.
    Спасибо!

    Успехов! Если есть ошибки/замечания/дополнения — пишите.

ссылка на оригинал статьи http://habrahabr.ru/post/270109/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *