lit-render-string の再取得でビルド破損を修正

shoelace-style/webawesome

ビルドプロセスで lit-render-string が正しく更新されず、Konnor が導入した変更でビルドが失敗するケースが発生していました。本修正はビルド完了後にモジュールを動的に再インポートし、最新の renderString 関数を取得することで問題を解消します。

背景

ビルドスクリプトは SSR 用の render-string.js を一度だけインポートし、以後その関数を保持していました。litRenderString はモジュール読み込み時に固定され、ビルドが再実行されても再取得されません。この挙動は生成物が変更された場合に古い実装が残り、実行時エラーを引き起こすリスクがあります。

Konnor が導入した変更により、render-string.js の出力がビルドごとに更新されるようになりました。ビルドが成功した後でも、スクリプトは旧バージョンの renderString を参照し続けます。結果として、SSR の出力が期待と乖離し、CI でのビルド失敗が観測されました。

したがって、ビルドプロセス全体の信頼性を確保するためには、最新のモジュールを毎回取得する必要があります。この要件を満たすには、インポート時にモジュールキャッシュをバイパスする手法が有効です。そこで本PRでは動的インポートとキャッシュバストを組み合わせた実装が選択されました。

技術的な変更

修正では litRenderString をデフォルトで単純パススルー関数として宣言し、ビルド完了後に上書きできるようにしました。この変数はスクリプト全体で使用され、SSR のレンダリングロジックに渡されます。宣言だけで動作に影響はなく、後続の動的再インポートに備える形となります。

let litRenderString = str => str;

let litRenderString = str => str; をファイル冒頭に追加しました。これにより、モジュールがまだ読み込まれていない段階でも関数呼び出しが安全に行えます。実際の実装はビルド成功時に差し替えられます。

ビルドが成功した後、spinner.succeed の直後で render-string.js をタイムスタンプ付きで再インポートし、litRenderString に最新の renderString を代入しています。?cachebust=${new Date().getTime()} クエリはモジュールキャッシュを回避し、常に新しいファイルが取得されます。この処理はビルドが失敗した場合には実行されず、エラーハンドリングに影響を与えません。

const mod = await import(`../dist/ssr/render-string.js?cachebust=${new Date().getTime()}`);
litRenderString = mod.renderString;

以前は ../dist/ssr/render-string.js を静的にインポートし、litRenderString を即座に取得していました。const { renderString: litRenderString } = await import('../dist/ssr/render-string.js'); の行を削除し、動的取得へ統一しました。これにより、モジュールがビルドごとに変化しても常に最新実装が使用されます。

以上の変更はスクリプトのロジックを大幅に変更せず、インポートタイミングのみを調整した点に留めています。ビルドフローや他の機能への副作用は報告されていません。結果として、Konnor が導入した変更に起因するビルド破損が解消されました。

設計判断

設計上はビルドごとに SSR 用レンダリング関数を再取得する方針が採られました。静的インポートではモジュールキャッシュが残り、生成物の差分が反映されません。動的インポートに切り替えることで、ビルドのたびに最新コードを確実に使用できます。

キャッシュバストとしてタイムスタンプクエリを付与する実装は、Node の ES モジュールローダがクエリ違いを別モジュールと見なす挙動を利用しています。この手法は追加の依存や設定変更を必要とせず、シンプルにキャッシュ回避が可能です。代替案として import.meta.resolve やモジュールキャッシュの手動削除が検討されましたが、コード可読性と安全性の観点から採用されませんでした。

動的再インポートは若干のオーバーヘッドを伴いますが、ビルド信頼性の向上という利益が上回ります。インポートはビルド成功時に1回だけ実行されるため、全体の処理時間への影響は最小です。設計者は信頼性を最優先し、実装の簡潔さを保つ選択を行いました。

まとめ

本修正により、render-string.js の変更がビルドプロセスに即座に反映され、Konnor が引き起こしたビルド破損が解消されます。動的インポートとキャッシュバストの組み合わせは、生成物が頻繁に変わる環境での安全なモジュール取得手段として有効です。今後も同様のパターンでモジュール更新が必要な箇所に適用すれば、ビルドの堅牢性を維持できるでしょう

記事メタデータ

Generated by:
gpt-oss-120b for DiffDaily
LLM Trace:
958934d6

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
gpt-oss-120b for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

リード文がタイトル直下に配置され、背景・技術的変更・設計判断・まとめの各セクションがあり、結論が独立しているので構成は適切です。

カスタムMarkdown構文 ⚠ WARNING

シンタックスハイライト・GitHubリンク記法の正確性

コードブロックは `言語:ファイルパス` 形式で正しく記述されていますが、PRリンクが `[PR #2508](URL)` となっており、仕様の `[ #2508 ](URL)` 形式と異なります。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

専門的な用語と実装詳細が中心で、エンジニア向けに適した内容です。

パラグラフ・ライティング ⚠ WARNING

トピックセンテンス・1段落1トピック・段落長

「背景」セクションの段落が9文と長すぎるため、可読性向上のために分割が推奨されます。その他の段落はトピックセンテンスで始まり、1段落1トピックの原則は守られています。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事中のコードブロックはDiffに記載された追加行と完全に一致し、削除された静的インポートも正しく言及されています。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

使用されている技術用語(litRenderString、renderString、キャッシュバスト、動的インポート)はPRやDiffと整合しており、誤用はありません。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

動的インポートとクエリキャッシュバストによる問題解決の説明はDiffの変更内容と一致しており、技術的に正確です。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記事の主張はPRタイトルやDiffの情報に基づいており、根拠のない数値や外部知識は含まれていません。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号 #2508 が正しく記載されています。その他の数値的記述はありません。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事タイトルはPRの「ビルドを修正する」目的を具体的に表現しており、矛盾はありません。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

LTSやリリース日程等、PRに記載されていない外部情報は記事に見られません。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

時間表現の歪曲はなく、PRの情報と一致しています。