Polymer 1.x to 2.x миграция

Миграция с Polymer 1.x на 2.x требует понимания изменений в архитектуре компонентов, синтаксисе и механизмах связывания данных. Polymer 2.x использует стандарты Web Components более строго, что отражается в структуре элементов, их определении и жизненном цикле. Основные аспекты миграции включают переход от старого синтаксиса Polymer({...}) к классам ES6, изменение способов объявления свойств и использования шаблонов.


Определение компонентов

В Polymer 1.x компоненты создавались через функцию Polymer({...}):

Polymer({
  is: 'my-element',
  properties: {
    message: {
      type: String,
      value: 'Hello'
    }
  }
});

В Polymer 2.x применяется ES6-классы и наследование от Polymer.Element:

class MyElement extends Polymer.Element {
  static get is() { return 'my-element'; }

  static get properties() {
    return {
      message: {
        type: String,
        value: 'Hello'
      }
    };
  }
}

customElements.define(MyElement.is, MyElement);

Ключевое изменение: компоненты теперь являются полноценными классами, что упрощает наследование и интеграцию с современным JavaScript.


Свойства и наблюдатели

Polymer 2.x сохраняет концепцию свойств и наблюдателей (observers), но изменилась форма их объявления:

  • Свойства теперь объявляются через static get properties().
  • Наблюдатели оформляются через static get observers():
static get observers() {
  return [
    'messageChanged(message)'
  ];
}

messageChanged(newValue) {
  console.log('Новое значение свойства:', newValue);
}

Это обеспечивает более предсказуемое поведение и совместимость с ES6.


Жизненный цикл компонентов

В Polymer 2.x жизненный цикл компонентов полностью соответствует стандартам Web Components:

  • connectedCallback() — вызывается при добавлении элемента в DOM.
  • disconnectedCallback() — при удалении из DOM.
  • ready() — инициализация, ранее выполняемая в Polymer({ ready() {...} }).
  • attributeChangedCallback() — реакция на изменения атрибутов.

Пример адаптации ready:

ready() {
  super.ready();
  console.log('Элемент готов к использованию');
}

Важно: super.ready() нужно вызывать для корректной инициализации базового класса.


Шаблоны и данные

Polymer 2.x поддерживает <template> и связывание данных через {{}} и [[]]:

  • {{}} — двухстороннее связывание.
  • [[]] — одностороннее связывание, предотвращает ненужные обновления.

Пример:

<template>
  <p>{{message}}</p>
  <input value="{{message::input}}">
</template>

В 2.x появилась строгая типизация и возможность указывать observer для свойств:

properties: {
  message: {
    type: String,
    value: '',
    observer: '_messageChanged'
  }
}

Модули и импорт

Polymer 1.x использовал HTML Imports:

<link rel="import" href="my-element.html">

Polymer 2.x поощряет использование ES6-модулей:

import './my-element.js';

Это повышает совместимость с современными сборщиками и позволяет использовать динамический импорт.


Совместимость и hybrid mode

Для постепенной миграции используется hybrid mode, где элементы совместимы с 1.x и 2.x. Основные правила:

  • Использовать Polymer({...}), но внутри объявлять свойства через static get properties().
  • Поддерживать <link rel="import"> для компонентов, еще не переведенных на ES6.
  • Сохранять старые события и наблюдатели для плавного перехода.

Пример гибридного компонента:

Polymer({
  is: 'hybrid-element',
  properties: {
    message: {
      type: String,
      value: 'Hello'
    }
  },
  ready() {
    console.log('Hybrid component ready');
  }
});

Позже его можно полностью перевести на класс ES6.


Обработка событий

В Polymer 2.x изменяется способ обработки пользовательских событий:

  • Используется стандартный метод this.dispatchEvent(new CustomEvent(...)).
  • Для подписки на события внутри шаблона применяется on-event="handler".

Пример:

<button on-click="handleClick">Нажать</button>
handleClick(e) {
  console.log('Клик по кнопке', e);
  this.dispatchEvent(new CustomEvent('button-clicked', { bubbles: true, composed: true }));
}

Отличие: обязательное использование bubbles и composed для корректной работы событий в Shadow DOM.


Стилевые изменения и Shadow DOM

Polymer 2.x полностью поддерживает Shadow DOM, что делает стили изолированными:

<style>
  :host {
    display: block;
    color: red;
  }
  p {
    font-weight: bold;
  }
</style>
  • :host — селектор для самого элемента.
  • Стили не «протекают» наружу, что повышает инкапсуляцию.

Для компонентов, использующих Shady DOM, можно сохранять обратную совместимость через ShadyCSS.


Рекомендации по миграции

  • Начинать с hybrid mode для постепенного перехода.
  • Переводить отдельные элементы на ES6-классы, сохраняя старый функционал.
  • Обновлять импорты и события в соответствии с стандартами Web Components.
  • Проверять жизненный цикл элементов и корректность работы свойств и наблюдателей.
  • Использовать современные инструменты сборки (Webpack, Rollup) для поддержки ES6-модулей.

Миграция с Polymer 1.x на 2.x улучшает совместимость с современным JavaScript, повышает предсказуемость работы компонентов и упрощает поддержку крупных проектов.