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

Насколько хорошо вы знаете веб-компоненты? Что бы вы хотели узнать о веб-компонентах?

Вот ответы на самые распространенные вопросы, которые мне часто задают.

Могут ли веб-компоненты работать без 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), где вы можете подписаться на мои статьи о веб-компонентах и ​​современном Интернете.