Astroで生成されるCSSファイルの名前を任意の形にしたいということがあったので、試した内容をメモ。
やりたかったこと
ビルドしたファイルをクライアントに納品して公開してもらうという案件で、サイト公開後の更新でCSSを変更した際に、CSSのファイル名を変更しないようにしたい(HTMLもアップロードしてもらう必要が出てくるため)、という内容がやりたいことになります。
結論としては、自分で試した範囲ではやりたかったことに沿った形にすることは難しそうでした。
サンプルコード
まずは動作確認用にいくつかページを用意します。
layouts/Layout.astroを以下のように変更します。
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<title>test</title>
</head>
<body>
<slot />
</body>
</html>
<style>
body {
margin: 0;
}
</style>
pages ディレクトリ内に下記3ページを用意します。
- トップページ(pages/index.astro)
- Aboutページ(pages/about/index.astro)
- Companyページ(pages/company.astro)
トップページの内容です。
---
import Layout from '../layouts/Layout.astro';
---
<Layout>
<h1>トップページ</h1>
<p>トップページの内容です。</p>
<p><a href="./about/">About</a></p>
<p><a href="./company/">Company</a></p>
</Layout>
<style>
h1 {
color: red;
font-size: 48px;
}
</style>
Aboutページの内容です。
---
import Layout from '../../layouts/Layout.astro';
import { Image } from 'astro:assets';
import Img from '../../assets/about/img.jpg';
---
<Layout>
<div class="about">
<h1>Aboutページ</h1>
<p>Aboutページの内容です。</p>
<Image src={Img} alt="" />
<p><a href="../">Top</a></p>
<p><a href="../company/">Company</a></p>
</div>
</Layout>
<style>
.about {
padding: 20px;
background-color: lightgray;
}
h1 {
color: blue;
font-size: 36px;
}
</style>
companyページの内容です。
---
import Layout from '../layouts/Layout.astro';
---
<Layout>
<h1>companyページ</h1>
<p>companyページの内容です。</p>
<p><a href="../">Top</a></p>
<p><a href="../about/">About</a></p>
</Layout>
<style>
h1 {
color: green;
font-size: 24px;
}
</style>
astro.config.mjs で、常にCSSを別ファイルで生成するようにします。
// @ts-check
import { defineConfig } from 'astro/config';
// https://astro.build/config
export default defineConfig({
build: {
inlineStylesheets: 'never'
},
});
これで動作確認の準備ができました。
対応前のデモページ
この時点でビルドを行うと、以下のようなCSSファイルが生成されます。
- _astro/company.CLFaVvkY.css(Companyページで設定した内容)
- _astro/index.BnFjbWKs.css(Aboutページで設定した内容)
- _astro/index.D0YpmbzK.css(トップページで設定した内容)
- _astro/index.TZrNw7dA.css(Layout.astro内で設定した内容)
ファイル名を変更する方法ですが、Viteの設定で変更ができるようです。
// @ts-check
import { defineConfig } from 'astro/config';
// https://astro.build/config
export default defineConfig({
build: {
inlineStylesheets: 'never'
},
vite: {
build: {
rollupOptions: {
output: {
assetFileNames: (assetInfo) => {
if (assetInfo.name?.endsWith(".css")) {
return "assets/[name][extname]";
}
return "assets/[name].[hash][extname]";
},
},
},
},
},
});
14~16行目がファイルがCSSの場合のファイル名の設定で、17行目がそれ以外の場合のファイル名の設定になります。
[name]が拡張子を除いたアセットのファイル名、[extname]がドットを含んだファイル拡張子になるようです。
assetFileNamesを設定するデモページ
設定後にビルドした結果は以下の通りで、ファイル名からハッシュ値を除くことはできたのですが、about/index.astro のような場合にディレクトリ名を使ったファイル名とすることができなさそうでした。
- assets/company.css(Companyページで設定した内容)
- assets/index.css(Layout.astro内で設定した内容)
- assets/index2.css(Aboutページで設定した内容)
- assets/index3.css(トップページで設定した内容)
ハッシュ値を除きつつ連番で固有のファイル名にはなっているのですが、この形だとやりたいことには沿えなさそうでした。
例として、pages/sitemap/index.astro を追加してみます。
---
import Layout from '../../layouts/Layout.astro';
---
<Layout>
<h1>Sitemapページ</h1>
<p>Sitemapページの内容です。</p>
</Layout>
<style>
h1 {
color: olive;
}
</style>
assetFileNamesの設定後にページを追加するデモページ
この状態でビルドを行った結果が下記になるのですが、連番毎のファイル内容が変わってしまうようでした。
- assets/company.css(Companyページで設定した内容)
- assets/index.css(Aboutページで設定した内容)
- assets/index2.css(Sitemapページで設定した内容)
- assets/index3.css(トップページで設定した内容)
- assets/index4.css(Layout.astro内で設定した内容)
結論としては、CSSをAstro管理外にする(publicに入れる形にする)などになりそうという気がします。
コメントが承認されるまで時間がかかります。