Astroプロジェクトのpublicディレクトリ内の JPEG/PNGファイルを、ビルド時にWebPに変換して公開する
🚀 AstroでのJPEG/PNGからWebPへの変換手順
高性能な画像処理ライブラリである Sharp を使用し、Astroのビルド前フック(prebuild)で一括変換を行います。
ステップ 1: Sharpのインストール
まず、プロジェクトの依存関係として Sharp をインストールします。Bash
npm install sharp
ステップ 2: 変換スクリプトの作成
scriptsディレクトリを作成し、JPEG/PNGファイルをスキャンしてWebPに変換するNode.jsスクリプトを作成します。このスクリプトは、publicディレクトリ内の画像を見つけ、Astroの出力先(dist)内の対応する場所にWebPファイルを生成します。
例: scripts/optimize-webp.mjsJavaScript
import sharp from 'sharp';
import fs from 'fs/promises';
import path from 'path';
// Astroプロジェクトのルートディレクトリを取得
const rootDir = process.cwd();
const publicDir = path.join(rootDir, 'public');
const distDir = path.join(rootDir, 'dist'); // Astroの標準的なビルド出力先
/**
* ディレクトリを再帰的にスキャンし、JPEG/PNGをWebPに変換する
*/
async function processDirectory(currentDir) {
// publicディレクトリからの相対パス
const relativePath = path.relative(publicDir, currentDir);
// distディレクトリ内の対応する出力パス
const outputDir = path.join(distDir, relativePath);
try {
const items = await fs.readdir(currentDir, { withFileTypes: true });
for (const item of items) {
const inputPath = path.join(currentDir, item.name);
if (item.isDirectory()) {
// サブディレクトリを再帰的に処理
await processDirectory(inputPath);
} else if (item.isFile() && /\.(jpe?g|png)$/i.test(item.name)) {
// WebPのファイル名と出力パスを定義
const webpFileName = item.name.replace(/\.(jpe?g|png)$/i, '.webp');
const outputWebpPath = path.join(outputDir, webpFileName);
// 出力先のディレクトリが存在しない場合は作成
await fs.mkdir(path.dirname(outputWebpPath), { recursive: true });
// Sharpを使ってWebPへ変換
await sharp(inputPath)
.webp({ quality: 80 }) // 変換品質を設定(80を推奨)
.toFile(outputWebpPath);
console.log(`✅ Converted: ${relativePath}/${item.name} -> ${path.relative(rootDir, outputWebpPath)}`);
}
}
} catch (error) {
console.error(`Error processing directory ${currentDir}:`, error.message);
}
}
// publicディレクトリから処理を開始
console.log('--- Starting WebP Optimization ---');
processDirectory(publicDir)
.then(() => console.log('--- WebP Optimization Complete ---'))
.catch(err => console.error('FATAL ERROR:', err));
ステップ 3: ビルドスクリプトの更新
package.jsonを開き、Astroのビルドコマンド(astro build)の前に、作成したスクリプトを実行するフック(prebuild)を設定します。JSON
// package.json
"scripts": {
"dev": "astro dev",
"start": "astro start",
"prebuild": "node scripts/optimize-webp.mjs", // 👈 これを追加
"build": "astro build",
"preview": "astro preview"
},
これで、npm run buildを実行すると、以下の流れで処理が行われます。
npm run prebuild:optimize-webp.mjsが実行され、public内のJPEG/PNGがWebPに変換され、distディレクトリ内に配置されます。npm run build:Astroがビルドを実行し、元の画像ファイル(JPEG/PNG)とWebPファイルの両方がdistにコピーされます。
ステップ 4: HTMLでのフォールバック設定
最後に、WebPと元のJPEG/PNGを両方配信するために、HTMLテンプレート内で <picture>タグを使用します。
<picture> <source srcset="/images/your-image.webp" type="image/webp"> <img src="/images/your-image.jpg" alt="画像の説明" width="800" height="600"> </picture>
これにより、すべてのブラウザで最適化された画像が配信されるようになります。


コメント