Web コンポーネント (view.component)
view.component エントリは、Web ホストが自動的に検出・注入・登録できる再利用可能なカスタム要素(Web コンポーネント)を記述します。ページとは異なり、コンポーネントは自身の iframe を持ちません — ページまたはホストのテンプレートが配置する任意の場所に現れることのできるカスタム HTML タグです。
コンポーネント実装の書き方については Web コンポーネント を参照してください。
フロントエンドのフィールド(package.json の wippy ブロック)
これらのフィールドは、FE 開発者が package.json の wippy ブロックに記述します。vite プラグインがビルド時に wippy-meta.json へ焼き込み、wippy/views はそこからデフォルト値として読み取ります。
このセクションのすべてのフィールドは、オペレーターが
_index.yamlでオーバーライドできます。常に YAML が優先されます。
| フィールド | 型 | デフォルト | 説明 |
|---|---|---|---|
type |
string | — | "component" または "widget" でなければなりません。"widget" がテンプレートの慣習です |
tagName |
string | — | カスタム要素名。HTML 仕様によりハイフンを含む必要があります |
props |
object | — | コンポーネントが受け付ける属性を記述する JSON Schema |
events |
object | — | コンポーネントが発行するカスタム DOM イベントを記述する JSON Schema |
package.json の wippy.type
Web コンポーネントのパッケージは、wippy ブロック内で "type": "widget" または "type": "component"("page" ではありません)を設定します。app-template は現在 "widget" を使用しており、vite プラグインはこのランタイム契約についてどちらのコンポーネント名も受け付けます。
{
"specification": "wippy-component-1.0",
"wippy": {
"tagName": "example-reaction-bar",
"type": "widget",
"props": { ... },
"events": { ... }
}
}
デプロイ時にはオペレーターの YAML の meta.tag_name が権威を持ち、バンドルされた値をオーバーライドします。wippy.tagName(package.json から wippy-meta.json へ焼き込まれたもの)は、YAML エントリが tag_name を省略した場合に wippy/views が使うフォールバックにすぎません(解決順: YAML の meta.tag_name → バンドルされた wippy.tagName)。驚きを避けるため両者は同期させておくべきですが、食い違った場合は YAML が勝ちます。
props スキーマ
package.json の wippy.props キーは、コンポーネントが受け付ける属性を記述する JSON Schema オブジェクトです。vite プラグインがこれを wippy-meta.json に含め、Web ホストは、チャットのアーティファクトレンダラーやタグサニタイザー(どの属性が正当かを知って除去しないようにする必要があります)といったコンシューマーへコンポーネントのメタデータを公開する際にこれを使います。
{
"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 の属性慣習(ケバブケース)に従います。スキーマの default 値は、属性が存在しない場合に Web コンポーネントの prop パーサーによって実行時にも適用されます。
events スキーマ
wippy.events キーは props と同じ形をとりますが、コンポーネントが useEvents() を通じて発行するカスタム DOM イベントを記述します。各キーがイベント名で、値はそのイベントの detail ペイロードの JSON Schema です。
{
"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 ホストのチャットメッセージサニタイザーは、wippy-meta.json の props.properties からコンポーネントの属性を許可リストに登録します。events スキーマは、ツールやコンシューマー向けに発行されるカスタムイベントを文書化するためのものであり、サニタイズされたチャットコンテンツ中で DOM イベントリスナー属性を通すために使われるものではありません。
オペレーターの設定 (_index.yaml)
これらのフィールドは、_index.yaml レジストリエントリの meta ブロックでオペレーターが設定します。大半は純粋なデプロイポリシー — ルーティング、アクセス制御、配信 — を表し、デプロイ時にのみ意味を持ち、package.json に記述面を持ちません(announced、secure、url、auto_register)。tag_name と entry_point の2つは異なり、これらは package.json で FE が記述し(wippy-meta.json に焼き込まれ)、YAML のキーはそのバンドル値に対するデプロイごとの任意のオーバーライドにすぎません。
announced、secure、url、auto_registerは純粋なデプロイポリシーであり、package.json では設定できません — 環境ごとにオペレーターが設定します。tag_nameとentry_pointは FE が記述するデフォルト値で、オペレーターは YAML でオーバーライドできます。
| フィールド | 型 | デフォルト | 説明 |
|---|---|---|---|
tag_name |
string | wippy.tagName |
package.json の wippy.tagName として FE が記述します(vite プラグインが必須とします)。YAML のキーはバンドル値をオーバーライドします。カスタム要素名。HTML 仕様によりハイフンを含む必要があります |
announced |
boolean | false |
コンポーネントが /api/public/components/list に現れるには true である必要があります。設定されていれば meta.public にフォールバックします。 |
auto_register |
boolean | false |
true → Web ホストが起動時にコンポーネントを自動ロードして登録します |
secure |
boolean | false |
認証を要求します |
url |
string | — | コンポーネントのビルド済みバンドルの静的マウントパス |
base_path |
string | "" |
プロジェクトルートを構成するために url へ追加する任意のサブパス。解決されるバンドル URL は <url>/<base_path>/<entry_point> として組み立てられます。ページと同一に扱われますが、現在の app-template のコンポーネントエントリはこれを省略しています |
entry_point |
string | wippy.browser → index.js |
package.json のトップレベル browser フィールドとして FE が記述します(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
自動ロードのための3つのゲート
Web ホストがコンポーネントを自動ロードするには、次の3つの条件がすべて同時に成り立つ必要があります。
-
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 ホスト内のページがマウントを終えると、ホストは次のシーケンスを実行します。
-
GET /api/public/components/list?auto_register=true— announced かつ自動登録対象のコンポーネントをすべて取得します。 -
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)から import します。これらはプロキシのdefineを再エクスポートしており、実行時に import マップが単一の@wippy-fe/proxyインスタンスへ解決します。defineヘルパーはnew URL(import.meta.url).searchParams.get('declare-tag')を読み、customElements.define(tagName, ElementClass)を呼びます。 -
Vue(または任意のフレームワーク)が
<example-reaction-bar>要素をレンダリングします。ブラウザーが要素をアップグレードし、connectedCallbackが発火し、WippyVueElementが shadow root 内に Vue アプリをマウントします。
auto_register: false が役立つ理由
auto_register: false を設定すると、コンポーネントはグローバルな自動ロードの走査から除外されます。次のような場合に適しています。
- コンポーネントが大きく、明示的に必要とするページでのみロードすべき場合。
- コンポーネントを呼び出し側で
loadByTagName('example-heavy-chart')(@wippy-fe/proxyから import)によりプログラム的に登録する場合。 - コンポーネントが、単体のカスタム要素としてではなく、別のバンドル内でのみ使われる内部の構成要素である場合。
import { loadByTagName } from '@wippy-fe/proxy'
await loadByTagName('example-heavy-chart')
遅延登録により、初期ページロードを軽量に保てます。loadByTagName() が API 経由で解決できるようにするには、コンポーネントには依然として announced: true が必要です — フラグが false の場合、GET /components/by-tag/{tag} エンドポイントは 404 "Component is not announced" を返します。