Веб-компоненты (view.component)
Запись view.component описывает переиспользуемый пользовательский элемент (веб-компонент), который Web Host может обнаружить, внедрить и зарегистрировать автоматически. В отличие от страницы, у компонента нет собственного iframe — это пользовательский HTML-тег, который может появиться везде, где его размещает шаблон страницы или хоста.
Рекомендации по написанию реализации компонента см. в разделе Веб-компонент.
Поля фронтенда (блок wippy в package.json)
Эти поля пишет FE-разработчик в блоке wippy файла package.json. Плагин vite запекает их в wippy-meta.json на этапе сборки, а wippy/views читает их оттуда как значения по умолчанию.
Все поля этого раздела могут быть переопределены оператором в
_index.yaml. YAML всегда имеет приоритет.
| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
type |
string | — | Должно быть "component" или "widget"; "widget" — соглашение шаблона |
tagName |
string | — | Имя пользовательского элемента; по спецификации HTML должно содержать дефис |
props |
object | — | JSON Schema, описывающая принимаемые компонентом атрибуты |
events |
object | — | JSON Schema, описывающая пользовательские DOM-события, которые компонент испускает |
wippy.type в package.json
Пакеты веб-компонентов устанавливают "type": "widget" или "type": "component" (не "page") внутри своего блока wippy. app-template в настоящее время использует "widget", а плагин vite принимает оба имени компонента для этого контракта среды исполнения.
{
"specification": "wippy-component-1.0",
"wippy": {
"tagName": "example-reaction-bar",
"type": "widget",
"props": { ... },
"events": { ... }
}
}
На этапе развёртывания YAML-поле оператора meta.tag_name авторитетно и переопределяет значение из бандла; wippy.tagName (запечённое в wippy-meta.json из package.json) — лишь запасной вариант, который wippy/views использует, когда YAML-запись опускает tag_name (порядок разрешения: YAML meta.tag_name → wippy.tagName из бандла). Держите эти два значения синхронными во избежание сюрпризов, но при расхождении побеждает YAML.
Схема props
Ключ wippy.props в package.json — объект JSON Schema, описывающий принимаемые компонентом атрибуты. Плагин vite включает его в wippy-meta.json, и Web Host использует его при предоставлении метаданных компонента таким потребителям, как рендерер артефактов чата и санитайзер тегов (которому нужно знать, какие атрибуты легитимны, чтобы не вырезать их).
{
"wippy": {
"props": {
"type": "object",
"properties": {
"reactions": {
"type": "array",
"items": { "type": "string" },
"default": ["👍", "👎", "❤️", "🎉", "🤔"],
"description": "Array of emoji reactions to display"
},
"allow-multiple": {
"type": "boolean",
"default": false,
"description": "Whether multiple reactions can be active simultaneously"
}
}
}
}
}
Имена атрибутов в properties следуют соглашению HTML-атрибутов (kebab-case). Значения default из схемы также применяются во время выполнения парсером props веб-компонента, когда атрибут отсутствует.
Схема events
Ключ wippy.events повторяет форму props, но описывает пользовательские DOM-события, которые компонент испускает через useEvents(). Каждый ключ — имя события; значение — JSON Schema для полезной нагрузки detail события.
{
"wippy": {
"events": {
"type": "object",
"properties": {
"reaction": {
"type": "object",
"properties": {
"emoji": { "type": "string" },
"count": { "type": "number" },
"active": { "type": "boolean" }
},
"description": "Fired when a reaction is toggled"
}
}
}
}
}
Санитайзер сообщений чата в Web Host добавляет в список разрешённых атрибуты компонента из props.properties в wippy-meta.json. Схемы событий документируют испускаемые пользовательские события для инструментов и потребителей; они не используются для пропуска атрибутов-обработчиков DOM-событий через санитизированное содержимое чата.
Конфигурация оператора (_index.yaml)
Эти поля задаёт оператор в блоке meta записи реестра _index.yaml. Большинство из них представляют чистую политику развёртывания — маршрутизацию, контроль доступа и раздачу, — которая имеет смысл только на этапе развёртывания и не имеет поверхности для описания в package.json (announced, secure, url, auto_register). Два поля, tag_name и entry_point, отличаются: они пишутся на стороне FE в package.json (запекаются в wippy-meta.json), а YAML-ключи — лишь необязательные переопределения на конкретное развёртывание этих значений из бандла.
announced,secure,urlиauto_register— чистая политика развёртывания, их нельзя задать в package.json: их устанавливает оператор для каждого окружения.tag_nameиentry_point— значения по умолчанию, задаваемые FE, которые оператор может переопределить в YAML.
| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
tag_name |
string | wippy.tagName |
Задаётся FE как wippy.tagName в package.json (обязательно для плагина vite); YAML-ключ переопределяет значение из бандла. Имя пользовательского элемента; по спецификации HTML должно содержать дефис |
announced |
boolean | false |
Должно быть true, чтобы компонент появился в /api/public/components/list. Откатывается к meta.public, если оно задано. |
auto_register |
boolean | false |
true → Web Host автоматически загружает и регистрирует компонент при запуске |
secure |
boolean | false |
Требует аутентификации |
url |
string | — | Статический путь монтирования для собранного бандла компонента |
base_path |
string | "" |
Необязательный подпуть, добавляемый к url для формирования корня проекта; итоговый URL бандла складывается как <url>/<base_path>/<entry_point>. Обрабатывается так же, как для страниц, хотя текущие записи компонентов в app-template его опускают |
entry_point |
string | wippy.browser → index.js |
Задаётся FE как поле верхнего уровня browser в package.json (запекается в wippy-meta.json); YAML-ключ переопределяет значение из бандла, откатываясь к index.js. Файл входного модуля; хост внедряет его как <script type="module"> |
Минимальная запись выглядит так:
- name: reaction-bar
kind: registry.entry
meta:
type: view.component
name: reaction-bar
tag_name: example-reaction-bar
announced: true
secure: false
auto_register: true
url: /app/wc/reaction-bar
entry_point: index.js
Три условия автозагрузки
Чтобы Web Host автоматически загрузил компонент, все три условия должны выполняться одновременно:
-
announced: true—wippy/viewsфильтрует по этому флагу на стороне сервера вlist_components.lua. Параметра запроса для обхода нет. Компонент сannounced: falseникогда не появится в/api/public/components/listнезависимо от любых других настроек. -
auto_register: true— функция хостаloadGlobalAutoloadWidgetsзапрашивает конечную точку списка с?auto_register=true. Компоненты без этого флага исключаются из отфильтрованного ответа. -
Тег ещё не зарегистрирован — перед внедрением скрипта хост проверяет
customElements.get(tagName). Если тег уже определён (например, после предыдущего перехода), хост пропускает внедрение, чтобы избежать повторного определения.
Если какое-либо из условий не выполнено, компонент молча отсутствует. Для проверки: curl /api/public/components/list?auto_register=true — ваш тег должен появиться в ответе.
Последовательность автозагрузки
Когда страница внутри Web Host заканчивает монтирование, хост выполняет следующую последовательность:
-
GET /api/public/components/list?auto_register=true— получает все объявленные, автоматически регистрируемые компоненты. -
Для каждого компонента, у которого
customElements.get(tagName)равноundefined, хост добавляет вdocument.head:<script type="module" src="/app/wc/reaction-bar/index.js?declare-tag=example-reaction-bar"></script>Параметр запроса
?declare-tag=— канал, сообщающий входному чанку, под каким именем пользовательского элемента регистрироваться. -
Входной чанк вызывает
define(import.meta.url, ElementClass). Авторы компонентов импортируютdefineиз@wippy-fe/webcomponent-vue(или@wippy-fe/webcomponent-core), которые реэкспортируютdefineиз прокси; во время выполнения import map разрешает его в единственный экземпляр@wippy-fe/proxy. Хелперdefineчитаетnew URL(import.meta.url).searchParams.get('declare-tag')и вызываетcustomElements.define(tagName, ElementClass). -
Vue (или любой другой фреймворк) отрисовывает элемент
<example-reaction-bar>. Браузер апгрейдит элемент, срабатываетconnectedCallback, иWippyVueElementмонтирует своё Vue-приложение внутри shadow root.
Зачем нужен auto_register: false
Установка auto_register: false исключает компонент из глобального прохода автозагрузки. Это уместно, когда:
- Компонент велик и должен загружаться только на страницах, которым он явно нужен.
- Компонент регистрируется программно через
loadByTagName('example-heavy-chart')(импортируется из@wippy-fe/proxy) в месте вызова. - Компонент — внутренний строительный блок, используемый только внутри другого бандла, а не как самостоятельный пользовательский элемент.
import { loadByTagName } from '@wippy-fe/proxy'
await loadByTagName('example-heavy-chart')
Ленивая регистрация позволяет первоначальной загрузке страницы оставаться лёгкой. Компоненту всё же нужен announced: true, чтобы loadByTagName() разрешил его через API: конечная точка GET /components/by-tag/{tag} возвращает 404 "Component is not announced", когда флаг равен false.