Lit SSR 用コンポーネントの作成

このパッケージは、実験的なパッケージの Lit Labs ファミリーの一部です。本番環境で Labs ソフトウェアを使用する場合のガイダンスについては、Lit Labs ページをご覧ください。

Lit のサーバー環境での Web コンポーネントのレンダリング方法は、効率的なサーバーレンダリングを実現するために、コンポーネントコードにいくつかの制限を設けています。コンポーネントを作成する際には、Lit SSR との互換性を確保するために、これらの考慮事項に留意してください。

注: このページに記載されている制限事項は、Lit SSR の改善に伴い変更される可能性があります。特定のユースケースをサポートしてほしい場合は、issue を作成するか、ディスカッションスレッドを開始してください。

ほとんどのブラウザ DOM API は Node 環境では使用できません。Lit SSR は、Lit テンプレートとコンポーネントのレンダリングに必要な最小限の DOM shim を利用します。使用可能な API の完全なリストについては、DOM エミュレーションページをご覧ください。

コンポーネントを作成する際には、サーバーではなく、**クライアントのみで**呼び出されるライフサイクルメソッドから命令型の DOM 操作を実行してください。たとえば、更新された DOM を測定する必要がある場合は、`updated()` を使用します。このコールバックはブラウザでのみ実行されるため、DOM に安全にアクセスできます。

サーバーで呼び出される特定のメソッドとブラウザ専用のメソッドのリストについては、以下のライフサイクルセクションをご覧ください。

Litコンポーネントを定義する一部のモジュールは、ブラウザ API を使用する副作用を持つ場合があります(たとえば、特定のブラウザ機能を検出するため)。そのため、ブラウザ以外の環境でインポートされるとモジュールが壊れる可能性があります。この場合、副作用コードをブラウザ専用のライフサイクルコールバックに移動するか、ブラウザでのみ実行されるように条件を設定できます。

単純なケースでは、特定の DOM アクセスに条件またはオプションのチェーンを追加することで、使用できない DOM API から保護するのに十分な場合があります。例えば

`lit` パッケージは、異なる環境をターゲットとする条件付きコードブロックを記述するために使用できる `isServer` 環境チェッカーも提供しています。

より複雑なユースケースでは、` "node"` 環境に特化した 条件付きエクスポート を利用することを検討してください。これにより、モジュールが Node で使用するためにインポートされるか、ブラウザで使用するためにインポートされるかによって、異なるコードを持つことができます。ユーザーは、Node からインポートされたかブラウザからインポートされたかに応じて、適切なバージョンのパッケージを取得します。エクスポート条件は、rollupwebpack などの一般的なバンドルツールでもサポートされているため、ユーザーはバンドルに適したコードを取り込むことができます。

設定例は次のとおりです。

Node エントリポイントファイルは手動で作成することも、バンドラーを使用して生成することもできます。

可能な場合は、Lit を公開されているコンポーネントにインラインでバンドルしないでください。

Lit パッケージは条件付きエクスポートを使用して Node とブラウザ環境に異なるモジュールを提供するため、`lit` を NPM に公開されるパッケージにバンドルすることは強くお勧めしません。バンドルすると、バンドルした環境専用の `lit` モジュールのみが含まれ、環境に基づいて自動的に切り替わりません。

ESBuild や Rollup などのバンドラーを使用してコードを変換する場合は、パッケージを *外部* としてマークすることで、コンポーネントにバンドルされないようにすることができます。ESBuild には、すべての依存関係を外部化する `packages` オプションがあります。または、external オプションで `lit` と関連パッケージのみをマークすることもできます。同様に、Rollup にも同等の "external" 設定オプションがあります。

Lit ライブラリコードをコンポーネントにバンドルする必要がある場合 (例: CDN 経由で配布する場合)、ブラウザ用と Node 用の 2 つのエントリポイントを作成することをお勧めします。バンドラーには、ブラウザや Node などのターゲットプラットフォームを選択するオプション、またはモジュールの解決に使用されるエクスポート条件を明示的に指定できるオプションがあります.

たとえば、ESBuild には `platform` オプションがあり、Rollup では `@rollup/plugin-node-resolve` の `exportConditions` オプションに ` "node"` を指定できます。

ブラウザと Node ターゲットのこれらのエントリポイントは、コンポーネントライブラリの `package.json` ファイルで指定する必要があります。詳細については、条件付きエクスポート を参照してください。

サーバーサイドレンダリング中は、特定のライフサイクルコールバックのみが実行されます。これらのコールバックは、コンポーネントの初期スタイルとマークアップを生成します。追加のライフサイクルメソッドは、ハイドレーション中およびコンポーネントがハイドレーションされた後のランタイム中にクライアントサイドで呼び出されます.

以下の表は、標準のカスタム要素と Lit のライフサイクルメソッド、および SSR 中に呼び出されるかどうかを示しています。すべてのライフサイクルは、要素の登録とハイドレーション後にブラウザで使用できます.

サーバーで呼び出されるメソッドには、shim されていないブラウザ/DOM API への参照を含めないでください。サーバーサイドで呼び出されないメソッドは、破損することなくこれらの参照を含めることができます.

メソッドがサーバーで呼び出されるかどうかは、Lit SSR が Lit Labs の一部である間は変更される可能性があります.

メソッドサーバーで呼び出される備考
constructor()はい ⚠️
connectedCallback()いいえ
attributeChangedCallback()いいえ
はいいいえ
adoptedCallback()いいえ
いいえはい ⚠️hasChanged()
shouldUpdate()いいえ
はいはい ⚠️willUpdate()
update()いいえ
はいはい ⚠️
render()いいえ
はいいいえ

ReactiveController

firstUpdated()
メソッドサーバーで呼び出される備考
constructor()はい ⚠️
いいえいいえ
updated()いいえ
いいえいいえ
「ReactiveController」へのパーマリンク いいえ

ディレクティブ

hostConnected()
メソッドサーバーで呼び出される備考
constructor()はい ⚠️
update()いいえ
はいはい ⚠️
いいえいいえhostDisconnected()
いいえいいえhostDisconnected()

レンダリングを続行する前に非同期結果を待機するメカニズムは現在ありません (非同期ディレクティブまたはコントローラーからの結果など)。ただし、将来的にはこれを許可するオプションを検討しています。現在の回避策は、サーバーでトップレベルのテンプレートをレンダリングする前に非同期作業を行い、データを何らかの属性またはプロパティとしてテンプレートに提供することです。

例えば

  • `asyncAppend()` や `asyncReplace()` などの非同期ディレクティブは、サーバーサイドではレンダリング可能な結果を生成しません。
  • `until()` ディレクティブは、常に優先順位の高い非 Promise プレースホルダー値のみを返します.

`@lit-labs/testing` パッケージには、Web Test Runner プラグインを利用して、`@lit-labs/ssr` を使用してサーバーサイドでレンダリングされるテストフィクスチャを作成するユーティリティ関数が含まれています。コンポーネントがサーバーサイドでレンダリング可能かどうかをテストするのに役立ちます。詳細については、readme をご覧ください。