Нерешённые проблемы кастомных элементов
Тред из второго дня моей недели в @jsunderhood.
Я обещал рассказать о не решенных проблемах кастомных элементов. В этом треде перечислю основные из них.
— jsunderhood (@jsunderhood) November 10, 2020
В моем списке есть пробелы, требующие доработок и новых API в браузерах, но это еще полбеды. На мой взгляд, более существенные проблемы проистекают из самой природы кастомных элементов.
— jsunderhood (@jsunderhood) November 10, 2020
Проблема № 1: кастомные элементы не работают с выключенным JS. Это заметно ограничивает область их применения. Есть черновик декларативного синтаксиса, но пока в стадии наброска.https://t.co/xJPfpKx88X
— jsunderhood (@jsunderhood) November 10, 2020
Проблема № 2: кастомные элементы не имеют кросс-браузерной поддержки форм. Form associated custom elements API уже добавлено в стандарт, но реализовано только в Chrome… Here we go again.https://t.co/5r84dRK4ZO
— jsunderhood (@jsunderhood) November 10, 2020
Проблема № 3: кастомный элемент с одним и тем же тегом можно определить только один раз. Это значит, что на странице нельзя использовать две версии одного компонента (будет exception).
— jsunderhood (@jsunderhood) November 10, 2020
Это одна из причин, почему Polymer долго использовал Bower: там плоское дерево и установить две версии одного пакета невозможно. В npm нужно следить за версиями и надеяться на dedupe.
— jsunderhood (@jsunderhood) November 10, 2020
В Vaadin мы обходим эту проблему с помощью pnpm. Там есть возможность гибкой настройки с помощью pnpmfile.js. Версии можно модифицировать в процессе установки в хуке readPackage.https://t.co/8Vfw2yBsYo
— jsunderhood (@jsunderhood) November 10, 2020
Проблема № 4: поскольку переопределять кастомные элементы нельзя, hot module replacement не работает. Есть полифилл, который патчит customElements.define и методы жизненного цикла.https://t.co/vJFf6x597B
— jsunderhood (@jsunderhood) November 10, 2020
Проблема № 5: кастомные элементы регистрируются глобально. В сочетании с невозможностью их переопределения это критично для больших проектов, разрабатываемых многими командами.
— jsunderhood (@jsunderhood) November 10, 2020
Решить эту проблему призван черновик Scoped Custom Element Registries, над которым работают представители Google и Salesforce. Сейчас идет обсуждение аспектов, связанных с Shadow DOM.https://t.co/w9JLgmg7pS
— jsunderhood (@jsunderhood) November 10, 2020
Пробная реализация в виде миксина для lit-element есть в проекте Open Web Components. Имеется ряд ограничений, в частности требование не определять используемые элементы глобально.https://t.co/gbOUOVq2Vo
— jsunderhood (@jsunderhood) November 10, 2020
Иногда базовые классы специально отделяют от определений кастомных элементов и выносят в отдельные файлы без сайд-эффектов. Я следую этому принципу. Статья на эту тему:https://t.co/8uHfoR4Xwp
— jsunderhood (@jsunderhood) November 10, 2020
Из комментариев: проблема № 6, связанная с жизненным циклом. Мне с ней сталкиваться не приходилось, но реализованное в браузерах поведение выглядит сложным и создает риски.https://t.co/0KiGFYIyam
— jsunderhood (@jsunderhood) November 10, 2020
Проект HowTo: Components для решения проблем с порядком загрузки использует Promise внутри connectedCallback. Как я понимаю, это единственный надежный способ. pic.twitter.com/J6SoUZYG2p
— jsunderhood (@jsunderhood) November 10, 2020
Напоследок упомяну некоторые черновики новых API, которые в перспективе могут облегчить жизнь разработчикам кастомных элементов. Прежде всего, это механизм обработки фокуса.https://t.co/FPO9UYU6TU
— jsunderhood (@jsunderhood) November 10, 2020
Второй пример — кастомные псевдо-классы, доступные за флагом в Chrome 79+. Скорее всего они, как и кастомные CSS свойства, будут требовать префикс из двух дефисов, например my-element:--activehttps://t.co/DTWheMImrh
— jsunderhood (@jsunderhood) November 10, 2020
Наконец, одно из недавних дополнений к стандарту — способность указывать ARIA-роли и поведение по умолчанию без использования атрибутов. Этот механизм появился в стабильном Chrome 81.https://t.co/F4jKppusJd
— jsunderhood (@jsunderhood) November 10, 2020