• #Nuxt3
  • #Vue
  • #PowerShell
  • #デプロイ
  • #コンポーネント設計
開発tax-lpメモ

LP改善 - サムネイル共通コンポーネント化・デプロイスクリプト・UTF-8 BOM問題

LPプロジェクトの改善作業。コンポーネントの重複解消、デプロイ計測の精度向上、Windows環境固有のエンコーディング問題の3つを対応した。

記事サムネイルの共通コンポーネント化

背景

各業種の LatestArticles コンポーネントに、記事画像が未設定時のプレースホルダーSVGがインラインで書かれていた。業種ごとに色テーマだけ異なる同じ構造のSVGが複数箇所にコピペされている状態。

ArticleThumbnail.vue

ArticleThumbnail.vue を作成し、プレースホルダーSVGを1箇所に集約した。

  • props で業種の色テーマ(primary / secondary)を受け取り、SVGの色を動的に切り替え
  • 記事に画像がある場合はそちらを表示、なければSVGプレースホルダーにフォールバック
  • 業種設定(industries.ts)から色テーマを取得する仕組み
<!-- 使用側 -->
<ArticleThumbnail
  :article="article"
  :color-theme="industryConfig.colorTheme"
/>

各業種の LatestArticles からインラインSVG(20行程度)を削除し、1行のコンポーネント呼び出しに置き換えた。

デプロイスクリプト改善

ウォームアップフェーズの分離

デプロイスクリプトで各業種のビルド時間を計測しているが、最初の業種だけNuxtのコールドスタート(依存解決やキャッシュ構築)が含まれ、他業種より時間がかかっていた。

修正として、計測対象の前に「ウォームアップビルド」フェーズを追加。ダミーの業種でビルドを1回走らせてキャッシュを温めてから、本番の計測を開始するようにした。これで業種間のビルド時間比較が公平になった。

.data 削除のリトライロジック

nuxt generate.data/ ディレクトリにSQLiteのロックファイルを残すことがあり、次のビルド前の削除が EBUSY で失敗するケースがあった。

# リトライ付き削除(最大3回、1秒待機)
$retryCount = 0
while ($retryCount -lt 3) {
    try {
        Remove-Item -Recurse -Force ".data"
        break
    } catch {
        Start-Sleep -Seconds 1
        $retryCount++
    }
}

Windowsのファイルロック解放タイミングの問題なので、少し待ってからリトライすれば成功する。

PowerShell UTF-8 BOM問題

症状

デプロイスクリプトに日本語コメントを追加したところ、PowerShellで実行時に構文エラーが発生。コメント行の日本語が文字化けしていた。

原因

WindowsのPowerShellは、BOM(Byte Order Mark)なしのUTF-8ファイルをシステムデフォルトのCP932(Shift_JIS)として解釈する。エディタ(VSCode等)はデフォルトでBOMなしUTF-8で保存するため、日本語を含むスクリプトが壊れる。

修正

ファイルをUTF-8 BOM付き(UTF-8 with BOM)で保存し直して解決。VSCodeの場合、ステータスバーの文字コード表示をクリックして「Save with Encoding」から UTF-8 with BOM を選択。

PowerShell 5.x(Windows標準)ではこの問題が起きるが、PowerShell 7.x(pwsh)ではBOMなしUTF-8がデフォルトで正しく読める。Windows標準のPowerShellを使う限り、日本語を含む .ps1 ファイルはBOM付きで保存する必要がある。

学び

  • インラインSVGの重複は、色テーマをpropsで受け取る共通コンポーネントに集約すると管理しやすい
  • ビルド時間の計測では、コールドスタートの影響を分離しないと比較が不公平になる
  • Windows + PowerShell 5.x では日本語入りスクリプトにUTF-8 BOMが必須。これはPowerShell 7.x移行まで付き合う問題