Перейти к содержанию

Собственные компоненты для Lit SSR

Этот пакет входит в семейство экспериментальных пакетов Lit Labs. Руководство по использованию программ Labs в производстве см. на странице Lit Labs.

Подход Lit к рендерингу веб-компонентов в серверной среде накладывает некоторые ограничения на код компонентов для достижения эффективного серверного рендеринга. При создании компонентов учитывайте эти соображения, чтобы обеспечить их совместимость с Lit SSR.

Примечание: Ограничения, перечисленные на этой странице, могут быть изменены по мере совершенствования Lit SSR. Если вы хотите, чтобы определенный вариант использования был поддержан, пожалуйста, подайте заявку или начните обсуждение.

Код только для браузеров

Большинство браузерных DOM API недоступны в среде Node. Lit SSR использует DOM shim, который является минимально необходимым для рендеринга шаблонов и компонентов Lit. Полный список доступных API можно найти на странице Эмуляция DOM.

При создании компонентов выполняйте императивные DOM-операции из методов жизненного цикла, которые вызываются только на клиенте, а не на сервере. Например, используйте updated(), если вам нужно измерить обновленный DOM. Этот обратный вызов выполняется только в браузере, поэтому доступ к DOM безопасен.

Список конкретных методов, которые вызываются на сервере, а какие - только в браузере, см. в разделе lifecycle ниже.

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

В простых случаях для защиты от недоступных API DOM может быть достаточно добавить условия или необязательную цепочку к определенным доступам к DOM. Например:

1
2
3
const hasConstructableStylesheets =
    typeof globalThis.CSSStyleSheet?.prototype
        .replaceSync === 'function';

Пакет lit также предоставляет средство проверки окружения isServer, которое можно использовать для написания условных блоков кода, нацеленных на различные окружения:

1
2
3
4
5
6
7
import { isServer } from 'lit';

if (isServer) {
    // only runs in server environments like Node
} else {
    // runs in the browser
}

Для более сложных случаев использования рассмотрите возможность использования условных экспортов в Node, которые специально соответствуют окружению "node", чтобы вы могли иметь разный код в зависимости от того, импортируется ли модуль для использования в Node или в браузере. Пользователи будут получать соответствующую версию пакета в зависимости от того, импортируется ли он из Node или из браузера. Условия экспорта также поддерживаются популярными инструментами пакетирования, такими как rollup и webpack, поэтому пользователи могут принести соответствующий код для вашего пакета.

Не собирайте Lit в опубликованные компоненты

Поскольку пакеты Lit используют условный экспорт для предоставления разных модулей окружению Node и браузеру, мы настоятельно не рекомендуем включать lit в ваши пакеты, публикуемые в NPM. Если вы это сделаете, ваш пакет будет включать только модули lit, предназначенные для окружения, которое вы включили в пакет, и не будет автоматически переключаться в зависимости от окружения.

Жизненный цикл

Во время рендеринга на стороне сервера запускаются только определенные обратные вызовы жизненного цикла. Эти обратные вызовы генерируют начальный стиль и разметку для компонента. Дополнительные методы жизненного цикла вызываются на стороне клиента во время гидратации и во время выполнения после гидратации компонентов.

В таблицах ниже перечислены стандартные методы жизненного цикла пользовательских элементов и Lit, а также указано, вызываются ли они во время SSR. Весь жизненный цикл доступен в браузере после регистрации элемента и гидратации.

Методы, вызываемые на сервере, не должны содержать ссылок на API браузера/DOM, которые не были шиммированы. Методы, которые не вызываются на стороне сервера, могут содержать такие ссылки, не вызывая сбоев.

Вызов метода на сервере может быть изменен, пока Lit SSR является частью Lit Labs.

Стандартный пользовательский элемент и LitElement

Метод Вызывается на сервере Примечания
constructor() Да ⚠️
connectedCallback() Нет
disconnectedCallback() Нет
attributeChangedCallback() Нет
adoptedCallback() Нет
hasChanged() Да ⚠️ Вызывается, когда свойство установлено
shouldUpdate() No
willUpdate() Да ⚠️ Вызывается перед render()
update() Нет
render() Да ⚠️
firstUpdate() Нет
updated() Нет

ReactiveController

| Метод | Вызывается на сервере | Примечания | | --- | --- | --- | --- | | constructor() | Да ⚠️ | | | hostConnected() | Нет | | | hostDisconnected() | Нет | | | hostUpdate() | Нет | | | | hostUpdated() | Нет | |

Директива

| Метод | Вызывается на сервере | Примечания | | --- | --- | --- | --- | | constructor() | Да ⚠️ | | | update() | Нет | | | render() | Да ⚠️ | | | | disconnected() | Нет | Только директивы Async | | reconnected() | Нет | Только директивы Async |

Асинхронность

В настоящее время не существует механизма ожидания асинхронных результатов перед продолжением рендеринга (например, результатов от асинхронных директив или контроллеров), хотя мы рассматриваем варианты, которые позволят сделать это в будущем. Текущее решение этой проблемы заключается в том, чтобы выполнять асинхронную работу до рендеринга шаблона верхнего уровня на сервере и предоставлять данные шаблону в виде какого-либо атрибута или свойства.

Например:

  • Асинхронные директивы, такие как asyncAppend() или asyncReplace(), не дадут никаких рендерируемых результатов на стороне сервера.
  • Директива until() приведет только к самому высокоприоритетному неперспективному значению placeholder.

Тестирование

Пакет @lit-labs/testing содержит служебные функции, использующие плагин Web Test Runner для создания тестовых приспособлений, которые выводятся на сервер с помощью @lit-labs/ssr. С его помощью можно проверить, могут ли ваши компоненты рендериться на стороне сервера. Подробнее см. в readme.

Комментарии