問題
PHPファイルからAstroで生成されたCSSやJavaScriptのファイル名を取得するために、Manifestファイル(jsやcssファイルパスが書かれたJSONデータ)生成を設定したが、distディレクトリ内に出力されていない。
具体的な症状
ビルド時、dist 内に .vite が生成され、その中にmanifest.jsonが生成されるが、ビルドが完了すると .vite のディレクトリごと削除されている。
構成
Webフレームワーク:Astro 7.0.2
サーバー:VPSサーバー
CMS:WordPress 7.0
前提
- 記事詳細はSNSからのシェアやSEOのためにAstroから分離したPHPファイルに
- PHPファイルからAstroが書き出した、ヘッダーやフッターなど共通パーツを読み込みたい
- Astroはビルドするたびに、ランダム文字列付きのJS・CSSファイルを生成するため、manifest.jsonの書き出しが必要
対処方法
修正前
astro.config.mjsに以下の設定を追加したが、dist内にmanifest.jsonは無し。
export default defineConfig({
outDir: './dist',
vite: {
build: {
manifest: 'manifest.json',
outDir: './dist',
},
},
});
修正後
astro.config.mjsにmanifest.jsonを強引に作成する関数を追加。
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const createAssetManifest = () => ({
name: 'create-asset-manifest',
hooks: {
'astro:build:done': async ({ dir }) => {
const distPath = fileURLToPath(dir);
const manifest = {};
function scanDir(currentPath) {
const files = fs.readdirSync(currentPath);
for (const file of files) {
const fullPath = path.join(currentPath, file);
const stat = fs.statSync(fullPath);
if (stat.isDirectory()) {
scanDir(fullPath);
} else if (file.endsWith('.js') || file.endsWith('.css')) {
const relativePath = path.relative(distPath, fullPath).replace(/\\/g, '/');
manifest[file] = relativePath;
}
}
}
scanDir(distPath);
fs.writeFileSync(
path.join(distPath, 'manifest.json'),
JSON.stringify(manifest, null, 2)
);
console.log('dist に manifest.json を生成完了');
},
},
});
さらにintegrationsに↑上記の関数名を追加
export default defineConfig({
integrations: [
createAssetManifest(),
],
});
これでdist内にmanifest.jsonを強引に生成!