Что такое веб компоненты
Веб-компоненты в реальном мире
Веб-компоненты – это общее название набора технологий, призванных помочь веб-разработчикам создавать переиспользуемые блоки. Компонентый подход создания интерфейсов хорошо закрепился во фронтенд-фреймворках, и кажется хорошей идеей встроить эту функциональность нативно в браузеры. Поддержка этой технологии браузерами уже достигла достаточного уровня, чтобы можно было всерьез задуматься об использовании этой технологии для своих рабочих проектов.
В этой статье мы посмотрим на особенности использования веб-компонентов, о которых почему-то не говорят евангелисты этих технологий.
Что такое веб-компоненты
Для начала нужно определиться, что именно входит в понятие веб-компонентов. Хорошее описание технологии есть на MDN. Если совсем коротко, то обычно в это понятие включают следующие возможности:
В качестве примера напишем hello-world компонент, который будет приветствовать пользователя по имени:
Посмотреть этот код в действии можно здесь.
Вам все равно понадобятся фреймворки
Распространено мнение, что внедрение веб-компонентов сделает фреймворки ненужными, потому что встроенной функциональности будет достаточно для создания интерфейсов. Однако, это не так. Кастомные html-тэги действительно напоминают Vue или React компоненты, но этого недостаточно, чтобы заменить их целиком. В браузерах не хватает возможности частичного обновления DOM – подхода к описанию интерфейсов, когда разработчик просто описывает желаемый html, а фреймворк сам позаботится об обновлении DOM–элементов, которые действительно изменились по сравнению с прошлым состоянием. Этот подход существенно упрощает работу с большими и сложными компонентами, так что без него придется тяжеловато.
Кроме того, в предыдущем разделе с примером компонента вы могли заметить, что нам пришлось написать какое-то количество кода для регистрации компонента и активации Shadow DOM. Этот код будет повторяться в каждом создаваемом компоненте, так что имеет смысл вынести его в базовый класс – и вот у нас уже есть зачатки фреймворка! Для более сложных компонентов нам понадобятся еще подписка на изменения атрибутов, удобные шаблоны, работа с событиями и т.д.
На самом деле фреймворки, основанные на веб-компонентах, уже существуют, например lit-element. Он использует веб-компоненты, а также lit-html для умного обновления DOM внутри компонента, чтобы не рендерить его целиком. Написание компонентов таким образом гораздо удобнее, чем через нативное API.
Еще часто говорят о пользе веб-компонентов в виде уменьшения размера загружаемого Javascript. Однако lit-element, который использует веб-компоненты весит в лучшем случае 6 кб, в то время как есть preact, который использует свои компоненты, похожие на React, но при этом весит в 2 раза меньше, 3 кб. Таким образом, размер кода и использование веб-компонентов вещи ортогональные и одно другому никак не противоречит.
Shadow DOM и производительность
Также стоит заметить, что у альтернативых подходов, вроде CSS-модулей, таких проблем нет, поскольку там все происходит на этапе сборки, и в браузер поступает обычный CSS.
Глобальные имена компонентов
Tree-shaking
Из глобального регистра компонентов следует еще одна проблема – у вас нет четкой связи между местом регистрации компонента и его использованием. Например, в React любой используемый компонент должен быть импортирован в модуль
Мы явным образом импортируем компонент Button. Если удалить импорт, то у нас произойдет ошибка в рендеринге. С веб-компонентами ситуация другая, мы просто рендерим html-тэги, а они магическим образом оживают. Аналогичный пример с кнопкой на lit-element будет выглядеть вот так:
Никакой связи между импортом и использованием нет. Если мы удалим импорт, но он останется в каком-то другом файле, то кнопка продолжит работать. Если импорт внезапно пропадет и из другого файла тоже, то только тогда у нас что-то сломается и это будет очень внезапно.
Отсутствие явной связи и между импортом и использованием не позволяет делать tree-shaking вашего кода, автоматическое удаление неиспользуемых импортов. Например, если мы импортируем несколько компонентов, но используем не все, они будут автоматически удалены:
Icon в этом файле не используется и будет спокойно удален. В ситуации с веб-компонентами этот номер не пройдет, потому что бандлер не в состоянии отследить эту связь. Ситуация очень напоминает 2010 год, когда мы вручную подключали в шапке сайта необходимые нам jquery-плагины.
Проблемы с типизацией
Javascript по своей природе динамический язык, и это нравится не всем. В больших проектах разработчики предпочитают типизацию, добавляя ее с помощью Typescript или Flow. Эти технологии прекрасно интегрируются с современными фреймворками типа React, проверяя корректность вызова компонентов:
С веб-компонентами так не получится. В предыдущем разделе рассказывалось, что место определения веб-компонента статически никак не связано с его использованием, и по этой же причине Typescript не сможет вывести допустимые значения для веб-компонента. Здесь на помощь может прийти JSX.IntrinsicElements – специальный интерфейс, откуда Typescript берет информацию для нативных тегов. Мы можем добавить туда определение для нашей кнопки
Возможно, по мере распространения стандарта, в Typescript придумают способ статически типизировать веб-компоненты, но пока при использовании веб-компонентов придется попрощаться с типобезопасностью.
Групповое обновление свойств
На стороне компонента мы определяем сеттер, который эти данные обработает:
В lit-element для этого есть удобный декоратор – property:
Однако, может случиться ситуация, что нам нужно обновить несколько свойств сразу:
Таким образом, реализация правильного обновления компонента это еще один аргумент за использование фреймворка вместо работы с веб-компонентами напрямую.
Выводы
После прочтения этой статьи может показаться, что веб-компоненты плохие и у них нет будущего. Это не совсем так, они могут пригодится в некоторых сценариях использования:
Есть также и вещи, которые я бы на веб-компонентах делать не стал:
Надеюсь эта информация окажется вам полезной при выборе технологического стека в этом году. Буду рад услышать что вы об этом думаете.
Web Components — будущее Web
Спустя какое время стало ясно, что основная идея Prototype вошла в противоречие с миром. Создатели браузеров ответили на возрождение Javascript добавлением новых API, многие из которых конфликтовали с реализацией Prototype.
Код на стороне клиента становится сложнее и объёмнее. Появляются многочисленные фреймворки, которые помогают держать этот хаос под контролем. Backbone, ember, angular и другие создали, чтобы помочь писать чистый, модульный код. Фреймворки уровня приложения — это тренд. Его дух присутствует в JS среде уже какое-то время. Не удивительно, что создатели браузеров решили обратить на него внимание.
Web Components — это черновик набора стандартов. Его предложили и активно продвигают ребята из Google, но инициативу уже поддержали в Mozilla. И Microsoft. Шучу, Microsoft вообще не при делах. Мнения в комьюнити противоречивые (судя по комментариям, статьям и т.д.).
Основная идея в том, чтобы позволить программистам создавать “виджеты”. Фрагменты приложения, которые изолированы от документа, в который они встраиваются. Использовать виджет возможно как с помощью HTML, так и с помощью JS API.
Я пару недель игрался с новыми API и уверен, что в каком-то виде, рано или поздно эти возможности будут в браузерах. Хотя их реализация в Chrome Canary иногда ставила меня в тупик (меня, и сам Chrome Canary), Web Components кажется тем инструментом, которого мне не хватало.
Стандарт Web Components состоит из следующих частей:
Фрагменты HTML, которые программист собирается использовать в будущем.
Содержимое тегов парсится браузером, но не вызывает выполнение скриптов и загрузку дополнительных ресурсов (изображений, аудио…) пока мы не вставим его в документ.
Инструмент инкапсуляции HTML.
Импорт фрагментов разметки из других файлов.
В Web Components больше частей и маленьких деталей. Некоторые я ещё буду упоминать, до каких-то пока не добрался.
Templates
Концепция шаблонов проста. Хотя под этим словом в стандарте подразумевается не то, к чему мы привыкли.
В современных web-фреймворках шаблоны — это строки или фрагменты DOM, в которые мы подставляем данные перед тем как показать пользователю.
В web components шаблоны — это фрагменты DOM. Браузер парсит их содержимое, но не выполняет до тех пор, пока мы не вставим его в документ. То есть браузер не будет загружать картинки, аудио и видео, не будет выполнять скрипты.
К примеру, такой фрагмент разметки в документе не вызовет загрузку изображения.
Пример работы шаблонов можно посмотреть здесь.
Все примеры в статье следует смотреть в Chrome Canary со включенными флагами:
Для Чего?
На данный момент существует три способа работы с шаблонами:
Минусы такого подхода в том, что браузер попытается “выполнить” код шаблона. То есть загрузить картинки, выполнить код скриптов и т.д.
Минус в том, что приходится работать со строками. Это создаёт угрозу XSS, нужно уделять дополнительное внимание экранированию.
У нет этих недостатков. Мы работаем с DOM, не со строками. Когда выполнять код, также решать нам.
Shadow DOM
Инкапсуляция. Этого в работе с разметкой мне не хватало больше всего. Что такое Shadow DOM и как он работает проще понять на примере.
Когда мы используем html5 элемент код выглядит примерно так:
Но на странице это выглядит так:
Мы видим множество контролов, прогресбар, индикатор длины аудио. Откуда эти элементы и как до них добраться? Ответ — они находятся в Shadow Tree элемента. Мы можем даже увидеть их в DevTools, если захотим.
Чтобы Chrome в DevTools отображал содержимое Shadow DOM, в настройках DevTools, вкладка General, раздел Elements ставим галочку Show Shadow DOM.
Содержимое Shadow DOM тега в DevTools:
Теория Shadow DOM
Shadow Tree — это поддерево, которое прикреплено к элементу в документе. Элемент в этом случае называется shadow host, на его месте браузер показывает содержимое shadow tree, игнорируя содержимое самого элемента.
Фишка shadow dom в том, что стили, определённые в нём с помощью
Зелёный фон в примере получит только `
` внутри shadow tree. То
есть стили «не вытекут» в основной документ.
Наследуемые стили
Авторские стили
Селекторы ^ и ^^
Инкапсуляция это здорово, но если мы всё таки хотим добраться до shadow tree и изменить его представление из стилей документа, нам понадобится молоток. И кувалда.
Селектор div ^ p аналогичен div p с тем исключением, что он пересекает одну теневую границу (Shadow Boundary).
Селектор div ^^ p аналогичен предыдущему, но пересекает ЛЮБОЕ количество теневых границ.
Зачем нужен Shadow DOM?
Shadow DOM позволяет изменять внутреннее представление HTML элементов, оставляя внешнее представление неизменным.
Custom Elements
API кастомного элемента
Прототип должен наследовать HTMLElement или его наследника,
например HTMLButtonElement :
Зачем нужны Custom Elements?
или
- хорошо подходят для низкоуровневой вёрстки, тогда как Custom Elements позволят писать модульный, удобочитаемый код на высоком уровне.
Shadow DOM и Custom Elements дают возможность создавать независимые от контекста виджеты, с удобным API и инкапсулированным внутренним представлением.
HTML Imports
Импорты — простое API, которому давно место в браузерах. Они дают возможность вставлять в документ фрагменты разметки из других файлов.
Object.observe()
Этот метод доступен в Chrome, если включить флаг Experimental Web Platform features.
TODO widget
Согласно древней традиции, вооружившись этими знаниями, я решил сделать простой TODO-виджет. В нём используются части Web Components, о которых я рассказывал в статье.
Добавление виджета на страницу сводится к одному импорту и одному тегу в теле документа.
Заключение
На мой взгляд, Web Components — это следующий шаг. Разработчики смогут создавать интерактивные виджеты. Их легко поддерживать, переиспользовать, интегрировать.
Код страницы не будет выглядеть как набор “блоков”, “параграфов” и “списков”. Мы сможем использовать элементы вроде “меню”, “новостная лента”, “чат”.
Конечно, стандарт сыроват. К примеру, импорты работают не так хорошо, как шаблоны. Их использование рушило Chrome время от времени. Но объём нововведений поражает. Даже часть этих возможностей способна облегчить жизнь web-разработчикам. А некоторые заметно ускорят работу существующих фреймворков.
Некоторые части Web Components можно использовать уже сейчас с помощью полифилов. Polymer Project — это полноценный фреймворк уровня приложения, который использует Web Components.
Ссылки
Eric Bidelman, серия статей и видео о Web Components:
Веб-компоненты проще, чем вы думаете
Когда я приходил на конференции и видел презентации на тему веб-компонентов, я всегда думал, что это не только изящно, но и довольно сложно. Тысяча строк JavaScript, чтобы сохранить всего 4 строки HTML. Докладчик или неизбежно скрывал за простыми вещами огромное количество JS кода, или погружался в сложные детали, тогда мои глаза начинали закрываться от скуки, и я начинал думать о том, покрывают ли мои суточные выплаты расходы на закуски.
Однако в недавнем проекте, созданном для легкого изучения HTML (Конечно, путем добавления зомби и глупых шуток), я решил, что необходимо описать каждый элемент HTML в спецификации. Не считая той конференции, я впервые начинал знакомство с и элементами, и, когда я захотел написать что-то интересное о них в проекте, мне пришлось углубиться в тему.
И в процессе углубления я понял: веб-компоненты проще, чем я думал.
Либо веб-компоненты прошли долгий путь развития с тех пор, как я мечтал о закусках на конференции, либо я позволил моему изначальному страху помешать по-настоящему узнать их, а возможно и то, и другое.
Я здесь, чтобы сказать вам: да, вы можете создать веб-компонент. Давайте оставим страх и даже закуски за дверью, чтобы сделать все вместе.
Начнем с
— это HTML элемент, позволяющий создать нам шаблон (HTML структуру для веб-компонентов).
Код
Тогда есть компонент
Код
Код
Использование веб-компонента
Технически, мы закончили писать собственный компонент и уже можем вставить в любое место, где захотим (Примечание переводчика: для полноценной работы компонента необходимо написать немного JS кода, о чем говорится далее).
Код
Стоит обратить внимание, что в названиях веб-компонентов должен быть дефис, чтобы предотвратить конфликт с HTML элементами, которые могут быть добавлены браузерами позже. Это то, о чем вы должны знать, когда дело касается веб-компонентов.
Все еще со мной? Не так уж и страшно, не правда ли? Что ж, минус зомби. Нам еще надо будет немного поработать, чтобы сделать замену возможной, именно здесь мы начинаем знакомство с JavaScript.
Регистрация компонента
Как я уже сказал ранее, вам нужно немного JavaScript кода, чтобы все это работало, но это не очень сложный, многострочный и глубокий код, как я всегда думал. Надеюсь, я смогу убедить вас в том, что все просто.
Вам нужна функция-конструктор, которая регистрирует веб-компонент. Иначе наше компоненты будет как нежить: она есть, но не полностью живая.
Вот конструктор, который мы будем использовать.
Код
Я оставил в коде подробные построчные комментарии, но не объяснил код на последней строке.
Код
Мы здесь делаем много работы. Во-первых, мы берем наш веб-компонент (this) и создаем скрытого шпиона, я имею в виду Shadow DOM. < mode: open >означает, что JavaScript может извне :root обращаться к элементам Shadow DOM и управлять ими, что-то вроде настройки доступа к компоненту через черный вход. Был создан Shadow DOM и мы добавляем к ней узел (Примечание переводчика: HTML Node). Этот узел будет полной копией шаблона, включая все элементы и текст шаблона. С шаблоном, прикрепленным к Shadow DOM из пользовательского компонента, элемент и slot атрибут берут на себя задачу сопоставления содержимого с тем, где оно должно находиться.
Проверьте это. Теперь мы можем объединить экземпляр одного и того же веб-компонента, отображая разный контент, просто изменив один элемент.
Код
Стилизация компонента
Возможно, вы заметили стилизацию в нашем примере. Как и следовало ожидать, у нас есть абсолютно все возможности для стилизации наших компонентов в CSS. На самом деле, мы можем включить
The Zombies are coming!
Таким образом, стили применяются только для компонента, что позволяет изолировать их благодаря теневой модели Shadow DOM.
Я предположил, что пользовательский компонент берет копию шаблона, вставляет контент, который вы добавили, и внедряет его на страницу, используя Shadow DOM. Хотя может показаться, что работа Shadow DOM похожа на обычное DOM дерево, но это не так. Контент в веб-компоненте остается на месте, а теневой DOM как бы накладывается сверху.
И с этого момента контент технически находится вне шаблона, любые селекторы и классы, используемые в шаблонном
Zombie Bob
Код
А вот и результат:
Несмотря на то, что есть еще пару ловушек и нюансов, я надеюсь, вы получили больше возможностей для работы с веб-компонентами, чем несколько минут назад. Возможно, будет хорошо, если вы добавите в свою работу какой-то нестандартный компонент, чтобы прочувствовать их и понять, где их использование имеет смысл.
Внедрение компонентого подхода в вебе: обзор веб-компонентов
Четыре из пяти самых запрашиваемых новых платформенных возможностей Edge на User Voice (Shadow DOM, Template, Custom Elements, HTML Imports) относятся к семейству API, называемых веб-компонентами (Web Components). В этой статье мы хотим рассказать о веб-компонентах и нашем взгляде на них, некоторой внутренней кухне, для тех, кто еще с ними не знаком, а также порассуждать на тему того, куда все это может эволюционировать в будущем. Это довольно-таки длинный рассказ, поэтому откиньтесь назад, возьмите кофе (или не кофеиновый напиток) и начинайте читать.
Внедрение компонентов: старая практика проектирования, ставшая новой для веба
Современные веб-приложения столь же сложны, как и любые другие программные приложения, и зачастую создаются несколькими людьми, объединяющими усилия для создания финального продукта. В таких условиях, чтобы повысить эффективность, естественно искать правильные способы разделения работы на участки с минимальными пересечениями между людьми и подсистемами. Внедрение компонентного подхода (в целом) — это то, как обычно решается такая задача. Любая компонентная система должна уменьшать общую сложность через предоставление изоляции, или естественных барьеров, скрывающих сложность одних систем от других. Хорошая изоляция также облегчает повторное использование и внедрение сервисных парадигм.
Изначально сложность веб-приложений в основном регулировалась со стороны сервера за счет разделения приложения на отдельные страницы, что требовало от пользователя соответствующим образом переходить в браузере с одной страницы на другую. С внедрением AJAX и связанных технологий разработчики смогли отказаться от потребности делать «переходы» между разными страницами веб-приложения. Для типичных сценариев вроде чтения почты или новостей ожидания пользователей изменились. К примеру, после логина в почту, вы можете «пользоваться почтовым приложением» с одного и того же адреса (URL) и находится на этой странице целый день (т.н. Single-Page Applications, SPA). Логика клиентских веб-приложений в таких ситуациях существенно усложняется, иногда она даже становится сложнее, чем на серверной стороне. Возможным разрешением данной сложности может являться дальнейшее разделение на компоненты и изоляция логики внутри одной страницы или документа.
Цель веб-компонентов в уменьшении сложности за счет изоляции связанных групп кода на HTML, CSS и JavaScript для выполнения общей функциональности в пределах контекста одной страницы.
Как разбивать на компоненты?
Так как веб-компоненты должны связать воедино HTML, CSS и JavaScript, необходимо учитывать существующие модели изоляции, присущие каждой из технологий, так как они влияют на сценарии и целостность веб-компонентов. Эти независимые модели изоляции включают:
Изоляция стилей в CSS
В рамках сегодняшней платформы не существует идеального и естественного способа разбить CSS на компоненты (хотя инструменты вроде Sass могут существенно помочь). Компонентная модель должна предлагать механизм для изоляции одного подмножества CSS от другого так, что правила не будут влиять друг на друга. К тому же, стили компонента должны применяться только к непосредственным частям компонента и более ни к чему другому. Легче сказать, чем сделать!
Внутри таблиц стилей CSS-правила применяются к документу, используя селекторы. Селекторы всегда рассматриваются как потенциально применимые ко всему документу, поэтому их область применения, в сущности, глобальная. Глобальное применение приводит к реальным конфликтам, когда несколько человек, работающих над проектом, смешивают вместе свои CSS-файлы. C пересечениями и повторениями селекторов можно бороться в четком порядке (например, каскады, специфичность, порядок следования исходников) для разрешения конфликтов, однако, такие действия, вполне вероятно, — совсем не то, чего хотели разработчики. Есть много потенциальных способов решения этой проблемы. Простое решение — перенести элементы и связанные стили, участвующие в формировании компонента из основного документа в другой документ (теневой документ) так, что они больше не будут «реагировать» на чужие селекторы. Это приводит ко второй проблеме: теперь, когда мы их разграничили, как некоторый стиль может пересечь границу (для управления снаружи компонента)? Очевидное возможное решение — это явно использовать JavaScript, но это выглядит как-то ужасно: полагаться на JavaScript для передачи стилей через границу, что кажется скорее пробелом в CSS.
Чтобы передать стили через границу компонента эффективным образом и при этом защитить структуру компонента (например, разрешить свободу изменения структуры без влияния стилей), существует два общих подхода, к которым многие склоняются: «частичная» стилизация с использованием псевдо-элементов и кастомные свойства (ранее известные как «переменные» CSS). Какое-то время также рассматривался супер-мощный кросс-граничный селектор ‘>>>’ (определен в CSS Scoping), но сегодня он общепризнан не самой удачной идеей, так как легко нарушает изоляцию компонентов.
Частичная стилизация позволит авторам компонента создавать собственные псевдо-элементы для стилизации, таким образом, выставляя наружу внешнему миру только часть своей внутренней структуры. Это похоже на модель, которую браузеры используют для выставления «частей» нативных элементов управления. Для целостности данного сценария авторам также понадобится некоторый способ ограничения набора стилей, которые могут применять к псевдо-элементу. Дополнительное исследование этой «частичной модели», базирующейся на пcевдо-элементах, может привести к появлению удобных стилистических примитивов, хотя проработка деталей еще потребует усилий. Дальнейшая работа над частичной моделью также должна рационализировать стилизацию родных элементов управления в браузерах (область, которая явно нуждается во внимании).
Кастомные свойства позволят авторам описывать значения стилей, которые они хотят повторно использовать в таблицах стилей (определяются как собственные имена свойств с двойным тире в качестве префикса). Кастомные свойства наследуются через под-дерево документа, позволяя селекторам переопределять значение кастомного свойства для конкретного под-дерева без затрагивания других под-деревьев. Кастомные свойства также смогут наследоваться через границы компонентов, предоставляя элегантный механизм стилизации компонентов, который при этом избегает раскрытия внутренней структурной природы компонента. Кастомные свойства оценивались при разработке разных компонентных фреймворков в Google и, по отчетам, позволяют покрыть большинство потребностей стилизации.
Из всех рассматриваемых на сегодня подходов для стилизации будущая «частичная» модель и текущая спецификация кастомных свойств, кажется, имеют наибольшие шансы реализации. Мы рассматриваем кастомные свойства в качестве нового ключевого члена семейства спецификаций веб-компонентов.
Другие подходы к изоляции CSS стилей
Для полноты картины, области видимости и изоляция CSS — это не такая черно-белая область, как могло показаться выше. На самом деле, несколько прошлых и текущих подходов предлагают варианты ограничения области применения и изоляции с различной применимостью к веб-компонентам.
CSS предлагает некоторые ограниченные формы изоляции селекторов в специфичных сценариях. Например, правило @media группирует набор селекторов вместе и применяет их при наступлении условий, соответствующих медиа-контексту (например, размер или разрешение вьюпорта, или медиа-тип — печать и т.п.); правило @page определяет некоторые стили, которые применимы только в контексте печати; правило @supports объединяет вместе селекторы для применения только, когда реализована поддержка специфичной CSS-функциональности — новая форма определения наличия функциональности в CSS); предложенное правило @document группирует селекторы для применения только тогда, когда документ, в котором загружены стили, соответствует условиям.
Области видимости в CSS (изначально написанные как часть работы над веб-компонентами) предлагают способ ограничивать применимость CSS-селекторов внутри одного HTML-документа. Спецификация вводит новое правило @scope, которое позволяет селектору определить корень(и) области применения и далее приводит к тому, что применение всех селекторов внутри правила @scope будет работать только в поддереве этого корны (а не на всем документе). Спецификация позволяет указывать корень области декларативно в HTML (например, предложен атрибут, пока реализованный только в Firefox; эта функциональность ранее была доступна в Chrome в качестве экспериментальной, но после была целиком удалена). Некоторые аспекты этой функциональности (к примеру, :scope, определенный в Selectors L4) также могут применяться для относительной оценки селекторов в новом API запросов в спецификации DOM.
Тут важно отметить, что @scope устанавливает только одно-направленную изоляцию границ: селекторы, содержащиеся внутри @scope, ограничены этой областью, в то время как любые другие селекторы (вне @scope) могут спокойной проникать внутри @scope (хотя они могут быть по-разному упорядоченным каскадом стилей). Это несколько неудачный дизайн, так как он не предоставляет ограничения области и изоляции от любых стилей, которые не находятся в подмножестве @scope — весь CSS должен по-прежнему «хорошо стыковаться», чтобы избежать стилизации внутри чужого правила @scope. См. также набросок @in-shafow-of от Таба, который лучше согласован с моделью защиты изоляции компонентов.
Другое предложение ограничения видимости — это сдерживания в CSS. Сдерживание области видимости — это в меньшей степени про изоляцию стилей и селекторов и в большей про изоляцию «композиции». Внутри свойства «contain» поведение некоторых возможностей CSS, которые имеют естественное наследование (в смысле применимости от родительского к дочернему элементу в документе, например, счетчики) будет блокировано. Основное применение этого для разработчиков состоит в том, чтобы указать, что некоторые элементы предполагают строгое «сдерживание», так что композиция, применимая к этому элементу и его поддереву никогда не будет затрагивать композицию других элементов документа. Эти обещания сдерживания (указываемые применением свойства «contain») позволяют браузерам оптимизировать композицию и отрисовку так, что «новая» композиция удерживаемого поддерева потребует только обновления этого поддерева, а не всего документа.
По мере того, как реализации технологий для веб-компонентов взрослеют среди браузеров и находят все больше публичного применения, дополнительные паттерны стилизации и проблемы могут появиться; мы ожидаем дальнейших инвестиций и последующего прогресса в различных предложениях в CSS для улучшения стилизации веб-компонентов.
JavaScript и области видимости
Весь JavaScript-код, который включен на страницу, имеет доступ к одному и тому же глобальному объекту. Как и другие языки программирования, JavaScript имеет области видимости, которые предоставляют некоторый уровень «приватности» для кода функции. Эти лексические области видимости используются для изоляции переменных и функций от остального глобального окружения. «Модульный шаблон» в JavaScript, популярный сегодня (использующий лексические области видимости), эволюционировал из потребности множества фреймворков на JavaScript «сосуществовать» в едином глобальном окружении без того, чтобы «наступать на пятки» друг другу (завися при этом от порядка загрузки).
Лексические области видимости в JavaScript – это однонаправленная изоляция границ: код внутри области может иметь доступ как ко внутреннему содержимому, так и к содержимому любой родительской области вплоть до глобальной, в то время как код снаружи области не имеет доступа к ее содержимому. Важным принципом является то, что однонаправленный способ изоляции отдает предпочтение коду внутри области, то есть защищает его. Код внутри лексической области имеет возможность защищать/прятать себя от остального окружения (или не делать этого).
Вклад, который лексические области видимости JavaScript вносят в реализацию веб-компонента, соответствует требованию иметь способ «закрытия» компонента так, что ее содержимое может быть разумно приватным.
Изоляция глобального объекта
Для некоторого кода может быть нежелательным, чтобы он имел общий доступ к глобальному окружению, как это было описано выше. К примеру, разработчик приложения может не доверять какому-то коду на JavaScript, хотя он и предоставляет существенную ценность. Характерный случай – реклама и рекламные фреймворки. Из соображений безопасности, необходимо, чтобы не доверенный код выполнялся в отдельном чистом скриптовом окружении (со своим собственным глобальным объектом). Чтобы достичь такого поведения сегодня (без включения в игру iframe элементов), разработчики могут использовать воркеры. Впрочем, недостаток этого решения в том, что воркеры не имеют доступа к элементам, то есть UI.
Есть ряд соображений, которые нужно учитывать при проектировании компонентов с поддержкой изоляции глобального объекта – особенно если изоляция будет подразумевать защищенные границы (подробнее ниже). На сегодня мы ожидаем, что изолированные компоненты не будут полностью доступны до тех пор, пока базовый набор спецификаций веб-компонентов не будет зафиксирован (то есть, это «отложено до следующей версии»). Однако, если мы потратим некоторое время на исследование того, как изолированные компоненты могут выглядеть, это может направить в правильное русло текущую работу. На некоторые предложения действительно стоит обратить внимание.
Изоляция глобального объекта – это важный нереализованный сценарий для веб-компонентов. А пока мы работаем над реализацией, можно, например, полагаться на самый успешный и распространенный на сегодня способ привнесения компонентности в веб: iframe-элемент.
Инкапсуляция элементов (iframe)
Iframe-элементы и их близкие родственники: элементы object, frameset и императивный API windows.open() – уже предоставляют возможность работать в изолированным поддеревом элементов. Однако, если компоненты подразумевают работу внутри одного документа, iframe включает внутри себя целый HTML-документ; как если бы два отдельных веб-приложения были размещены совместно, просто одно внутри другого. У каждого уникальные адрес документа, глобальное окружение для скриптов и область видимости CSS; каждый документ полностью отделен от другого.
Это все не в первый раз
Современные веб-компоненты
После провала первых двух попыток, пришло время попробовать запустить игру в компоненты снова, на этот раз делом занялся Google. Используя концепции, описанные в XBL в качестве стартовой точки, монолитная компонентная система была разбита на коллекцию строительных блоков для компонентов. Эти строительные блоки позволили веб-разработчикам экспериментировать с отдельными полезными возможностями до того, как общее видение для веб-компоненты будет полностью определено. Компонентность самого подхода и разработка отдельных полезных возможностей позволили продвинуться ближе к успеху. Практически каждый может найти в веб-компонентах что-то полезное для своего приложения!
Эта новая волна веб-компонентов привела к формированию набора конкретных примеров использования, объясняющих, как существующие встроенные элементы работают в рамках сегодняшней веб-платформы. В теории, веб-компоненты позволят разработчикам прототипировать новые типы HTML элементов с той же точностью и характерными чертами, как и у нативных элементов (на практике обеспечение доступности в HTML является сегодня особенно трудным в достижении).
Ясно, что полный набор всех технологий, необходимых для покрытия всех сценариев использования веб-компонентов, не будет реализован в браузерах сразу. Разработчики браузеров работают вместе, чтобы согласовать базовый набор технологий, который можно консистентно реализовать прежде, чем двигаться к дополнительным сценариям.
Веб-компоненты: следующее поколение
Как мы отметили в начале данной статьи, построить полнофункциональные веб-компоненты – это большое приключение. Несколько идей для развития и заполнения пробелов в текущем поколении возможностей уже начало циркулировать среди разработчиков (это не полный список!):
Наконец, хотя это и не считается официально частью веб-компонентов, старый добрый iframe не должен списываться со счетов. Как обсуждалось, iframe – это все еще очень часто используемая функциональность веб-платформы, подходящая для создания сущностей, похожих на компоненты. Было бы полезным понять и потенциально улучшить «компонентную» историю iframe. К примеру, дальнейшее изучение и адресация проблем с кажется хорошей темой для начала дискуссии.
Веб-компоненты – это поворотный моменты для веба. Мы рады продолжать поддерживать и вносить свой вклад в это приключение. Делитесь вашим мнением с нами в твиттере @msedgedev.