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移行まで付き合う問題