🔥

Тред (Сергей Куликов)


Я обещал рассказать о не решенных проблемах кастомных элементов. В этом треде перечислю основные из них.

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

Проблема № 1: кастомные элементы не работают с выключенным JS. Это заметно ограничивает область их применения. Есть черновик декларативного синтаксиса, но пока в стадии наброска. github.com/WICG/webcompon…

Проблема № 2: кастомные элементы не имеют кросс-браузерной поддержки форм. Form associated custom elements API уже добавлено в стандарт, но реализовано только в Chrome… Here we go again. web.dev/more-capable-f…

Проблема № 3: кастомный элемент с одним и тем же тегом можно определить только один раз. Это значит, что на странице нельзя использовать две версии одного компонента (будет exception).

Это одна из причин, почему Polymer долго использовал Bower: там плоское дерево и установить две версии одного пакета невозможно. В npm нужно следить за версиями и надеяться на dedupe.

В Vaadin мы обходим эту проблему с помощью pnpm. Там есть возможность гибкой настройки с помощью pnpmfile.js. Версии можно модифицировать в процессе установки в хуке readPackage. pnpm.js.org/en/pnpmfile#ho…

Проблема № 4: поскольку переопределять кастомные элементы нельзя, hot module replacement не работает. Есть полифилл, который патчит customElements.define и методы жизненного цикла. github.com/vegarringdal/c…

Проблема № 5: кастомные элементы регистрируются глобально. В сочетании с невозможностью их переопределения это критично для больших проектов, разрабатываемых многими командами.

Решить эту проблему призван черновик Scoped Custom Element Registries, над которым работают представители Google и Salesforce. Сейчас идет обсуждение аспектов, связанных с Shadow DOM. github.com/WICG/webcompon…

Пробная реализация в виде миксина для lit-element есть в проекте Open Web Components. Имеется ряд ограничений, в частности требование не определять используемые элементы глобально. open-wc.org/docs/developme…

Иногда базовые классы специально отделяют от определений кастомных элементов и выносят в отдельные файлы без сайд-эффектов. Я следую этому принципу. Статья на эту тему: component.kitchen/blog/posts/sup…

@jsunderhood Я бы в список добавил еще хаотичный порядок connectedCallback, из-за которого нельзя делать нормальную композицию компонентов: twitter.com/justboriss/sta… Вкупе с elements upgrade это создает огромное поле для наступания на грабли.
Из комментариев: проблема № 6, связанная с жизненным циклом. Мне с ней сталкиваться не приходилось, но реализованное в браузерах поведение выглядит сложным и создает риски. twitter.com/justboriss/sta…

Проект HowTo: Components для решения проблем с порядком загрузки использует Promise внутри connectedCallback. Как я понимаю, это единственный надежный способ.
notion image

Напоследок упомяну некоторые черновики новых API, которые в перспективе могут облегчить жизнь разработчикам кастомных элементов. Прежде всего, это механизм обработки фокуса. github.com/WICG/webcompon…

Второй пример — кастомные псевдо-классы, доступные за флагом в Chrome 79+. Скорее всего они, как и кастомные CSS свойства, будут требовать префикс из двух дефисов, например my-element:--active github.com/WICG/webcompon…

Наконец, одно из недавних дополнений к стандарту — способность указывать ARIA-роли и поведение по умолчанию без использования атрибутов. Этот механизм появился в стабильном Chrome 81. chromestatus.com/feature/596210…