Вот что вам нужно знать

Насколько хорошо вы знаете веб-компоненты? Что бы вы хотели узнать о веб-компонентах?
Вот ответы на самые распространенные вопросы, которые мне часто задают.
Могут ли веб-компоненты работать без JavaScript?
Да, веб-компоненты могут быть отображены без JavaScript через Declarative Shadow DOM.
Обычно Shadow Root прикрепляется к веб-компоненту (технически к пользовательскому элементу) через JavaScript:
const shadowRoot = this.attachShadow({mode: 'open'});
this.shadowRoot.innerHTML = `<p>Hi there!</p>`;
Без JavaScript вы не сможете создать Shadow Root таким образом.
Но декларативный теневой DOM позволяет вам определить теневой корень декларативно прямо в HTML:
<host-element>
<template shadowroot="open">
<slot></slot>
</template>
<h2>Light content</h2>
</host-element>
Когда синтаксический анализатор HTML встречает этот HTML-код, он немедленно применяет элемент <template> с атрибутом shadowroot="open" в качестве теневого корня <host-element>, в результате чего получается следующий HTML-код без необходимости использования JavaScript:
<host-element>
#shadow-root (open)
<slot>
↳
<h2>Light content</h2>
</slot>
</host-element>
Поскольку для этого не требуется JavaScript, декларативный теневой DOM можно использовать для рендеринга веб-компонентов на стороне сервера.
Теперь не бойтесь, что теперь вам нужно будет писать все свои веб-компоненты с этим синтаксисом. Это как бы противоречит цели инкапсуляции Shadow DOM.
При рендеринге HTML-страницы на стороне сервера вы можете просто получить корень декларативной тени для своего элемента с помощью нового метода getInnerHTML:
const el = document.querySelector('host-element');
const html = el.getInnerHTML({includeShadowRoots: true});
// html is now:
`<host-element>
<template shadowroot="open"><slot></slot></template>
<h2>Light content</h2>
</host-element>`
getInnerHTML работает так же, как innerHTML, но вы можете передать {includeShadowRoots: true} в качестве аргумента, который также вернет Shadow DOM элемента.
На момент написания вы можете опустить этот аргумент в Chrome, и он по умолчанию вернет Shadow Root.
Внутри скрипта на стороне сервера вы можете просто заменить содержимое <host-element> этим html, и Shadow Root вашего элемента теперь будет отображаться без JavaScript.
Имейте в виду, что декларативный теневой DOM заботится только об рендеринге вашего веб-компонента без JavaScript.
Для взаимодействия, такого как щелчок и т. д., вам все равно понадобится JavaScript, но это относится к любому компоненту.
На момент написания статьи декларативный теневой DOM поддерживается только в Chrome, Edge и Opera.
Поддерживает ли React веб-компоненты?
Вы можете использовать веб-компоненты внутри любой инфраструктуры JavaScript, и React также поддерживает это, но вам, вероятно, потребуется написать оболочку для вашего веб-компонента.
Из всех фреймворков JS React не самый простой для интеграции веб-компонентов.
Почему вы предпочитаете веб-компоненты фреймворкам?
Как я уже писал, вы можете использовать веб-компоненты с любым фреймворком, поэтому вам не нужно выбирать.
Но преимущества веб-компонентов заключаются в том, что они стандартны, могут использоваться где угодно (это всего лишь элементы HTML) и предоставляют действительно ограниченный CSS.
Что такое ограниченный CSS?
CSS, который вы определяете внутри своего веб-компонента, применяется к вашему компоненту только.
Это не повлияет ни на какие элементы за пределами вашего веб-компонента, и CSS для внешнего документа не будет применяться к вашему компоненту, за исключением некоторых стандартных стилей.
Это означает, что веб-компоненты предоставляют настоящую область CSS без каких-либо необходимых соглашений об именах.
Как веб-компоненты работают со специальными возможностями?
Прелесть веб-компонентов в том, что они являются обычными HTML-элементами, такими же, как нативные элементы, такие как <p>, <div>, <h1> и т. д.
Это означает, что обеспечение доступности веб-компонентов ничем не отличается от обеспечения доступности других элементов HTML.
Вы можете добавить метки арии, обработчики клавиатуры и фокуса и т. д.
Могу ли я использовать внешний CSS?
Да, ты можешь.
Хотя есть лучшие способы стилизации веб-компонентов, вы можете просто загрузить таблицу стилей в веб-компонент, используя <link rel="stylesheet">:
class HostElement extends HTMLElement {
constructor() {
super();
const shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.innerHTML = `
<link rel="stylesheet" href="/path/to/external.css">
<slot></slot>
`;
}
}
Другой, еще более интересный вариант — использовать конструируемые таблицы стилей, которые позволяют определять и подготавливать общие стили CSS, а затем применять эти стили к нескольким теневым корням.
Это позволяет вам поместить общий CSS в такой файл:
// shared-css.js
const css = `h1 {
color: red;
}`
const sheet = new CSSStyleSheet();
sheet.replaceSync(css);
export {
sheet
}
который вы затем можете использовать в нескольких веб-компонентах, например:
import {sheet} from './shared-css.js';
class HostElement extends HTMLElement {
constructor() {
super();
const shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.adoptedStyleSheets = [sheet];
shadowRoot.innerHTML = `
<h1>Hi there!</h1>
`;
}
}
Могу ли я использовать SASS с веб-компонентами?
Вы, вероятно, можете, но вам могут понадобиться только переменные, поскольку Shadow DOM может значительно упростить ваш CSS, а переменные уже доступны через Пользовательские свойства CSS.
Поэтому, хотя вы можете использовать SASS, он вам, вероятно, не понадобится.
Нужна ли мне сторонняя библиотека для использования веб-компонентов?
Нет, это не так.
Веб-компоненты теперь поддерживаются во всех браузерах. Для некоторых экспериментальных функций может потребоваться полифилл, но основные функции теперь доступны везде.
Помните, что веб-компоненты ничем не отличаются от обычных элементов HTML и будут рассматриваться браузерами как таковые.
Можно ли отображать веб-компоненты на стороне сервера?
Да, могут с Declarative Shadow DOM. Смотрите первый вопрос.
Какие самые важные плюсы?
Веб-компоненты — это просто стандартные элементы HTML, которые можно использовать где и которые можно интегрировать в любую структуру.
Вам не нужен сторонний код для рендеринга и использования веб-компонентов. Поскольку это обычные HTML-элементы, браузеры уже знают, как с ними эффективно обращаться.
В то время как фреймворки приходят и уходят, веб-компоненты являются стандартом, который вряд ли когда-либо устареет.
Еще одним очень важным плюсом является то, что вы можете полностью инкапсулировать HTML и CSS вашего компонента, так что у вас действительно ограниченный CSS.
Это позволяет вам значительно упростить CSS вашего компонента, поскольку он действительно имеет ограниченную область действия и не требует никаких соглашений.
Какие самые важные минусы?
Веб-компоненты не предоставляют готовых функций, таких как привязка данных и декларативные шаблоны, которые есть у фреймворков (хотя реализовать их несложно).
OMG, веб-компоненты не реактивны???
Веб-компоненты не предоставляют готовых функций, таких как реактивность и декларативные шаблоны, как это делают большинство фреймворков.
Но реализовать их не сложно:
Вы можете использовать что-то столь же простое, как сеттер, для реализации привязки данных.
Вот намеренно упрощенный пример:
class HostElement extends HTMLElement {
constructor() {
super();
const shadowRoot = this.attachShadow({mode: 'open'});
this._name = 'John';
shadowRoot.innerHTML = `
<h1>
Hi <span data-bind="name">${this._name}</span>
</h1>
`;
}
set name(value) {
this._name = value;
this.shadowRoot
.querySelectorAll('[data-bind="name"]')
.forEach((element) => element.textContent = value);
}
get name() {
return this._name;
}
}
Здесь элементы, привязанные к свойству, имеют атрибут data-bind, содержимым которого является имя свойства.
Внутри сеттера просматриваются все соответствующие элементы, и их свойству textContent присваивается новое значение.
Конечно, это может быстро запутаться, если у вас много связанных свойств, поэтому в таких случаях, вероятно, лучше использовать такие инструменты, как lit или StencilJS, но я надеюсь, что вы поняли идею.
Могу ли я использовать 11ty для компиляции веб-компонентов в HTML?
Веб-компоненты являютсяHTML, поэтому компилировать в HTML нечего.
Это уже HTML.
Веб-компоненты — это просто настраиваемые элементы HTML, которые можно использовать на любой HTML-странице.
Всегда ли разумно использовать Shadow DOM?
Это действительно зависит от вашего варианта использования, но обычно Shadow DOM будет хорошо подходить, поскольку по определению веб-компонент — это автономная единица, которая выиграет от инкапсуляции HTML и CSS.
Но если вам это не нужно, вы всегда можете создать веб-компонент, который не использует Shadow DOM.
Каков твой вопрос?
Я надеюсь, что эта статья ответила на некоторые из ваших вопросов о веб-компонентах.
Если у вас есть другие вопросы, пожалуйста, оставьте комментарий здесь или отправьте мне сообщение в Твиттере (@dannymoerkerke), где вы можете подписаться на мои статьи о веб-компонентах и современном Интернете.