はじめに
担当: 守矢 ![]()
以前、.NET 8 / Blazor 環境で
asp-append-version 相当のキャッシュバスティングを自前実装した記事を書きました。
Blazor では MVC / Razor Pages のように asp-append-version を使えない場面があり、
静的ファイルの内容ハッシュを元に ?v= を付ける仕組みを用意して対応しました。
一方で、.NET 10 の Blazor テンプレートを確認すると、最初から次のようなコードになっていました。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="/" />
<ResourcePreloader />
<link rel="stylesheet" href="@Assets["lib/bootstrap/dist/css/bootstrap.min.css"]" />
<link rel="stylesheet" href="@Assets["app.css"]" />
<link rel="stylesheet" href="@Assets["BlazorApp3.styles.css"]" />
<ImportMap />
<link rel="icon" type="image/png" href="favicon.png" />
<HeadOutlet />
</head>
<body>
<Routes />
<ReconnectModal />
<script src="@Assets["_framework/blazor.web.js"]"></script>
</body>
</html>
今回は、この @Assets[...] が何をしているのかと、
.NET 9 以降で静的ファイルのキャッシュバスティングがどう変わったのかを、.NET 10 テンプレートでの確認結果とあわせて整理します。
.NET 9 以降の静的アセット管理
テンプレートでは静的ファイル参照が標準化されている
.NET 10 で Visual Studio から Blazor プロジェクトを作成すると、
App.razor の時点で静的ファイル参照が @Assets[...] になっています。
<link rel="stylesheet" href="@Assets["app.css"]" />
<link rel="stylesheet" href="@Assets["BlazorApp3.styles.css"]" />
<script src="@Assets["_framework/blazor.web.js"]"></script>
この時点で、静的アセット管理がテンプレートに組み込まれていることが分かります。
(従来は意識的に実装していた部分が、標準機能として提供されている形です)
つまり、少なくとも新規の .NET 9 以降の Blazor Web App では
- 自前で
?v=を付ける - 静的ファイル用のサービスを作る
といったことを、最初から意識しなくてもよい形になっています。
ブラウザではフィンガープリント付きファイルとして配信される
実際にブラウザの開発者ツールで確認すると、
CSS ファイルは次のような形で配信されていました。
BlazorApp3.mmhkwg284d.styles.cssapp.khy4loq6vu.css
ファイル名自体にハッシュが含まれています。
つまり .NET 9 以降の Blazor Web App では、以前のように
app.css?v=xxxxx
というクエリ文字列方式ではなく、
app.khy4loq6vu.css
のような フィンガープリント付きファイル名 で静的ファイルを管理していることが確認できます。
.NET 8 と比較してどう変わったのか
.NET 8 で自前実装していたときは、
「URL にバージョンを付けてブラウザキャッシュを避ける」ことを自分で考える必要がありました。
一方、.NET 9 以降では
-
@Assets[...]で静的ファイルを参照する - ビルド / 配信側でフィンガープリント付きアセットに解決される(アプリ側で意識する必要がない)
という形になっていて、利用する側のコードはかなりシンプルです。
要するに、.NET 8 では自前実装が必要だった部分を、.NET 9 以降ではフレームワーク側が吸収してくれる形になっています。
公式ドキュメント
このあたりは Microsoft Docs にまとまっています。
Static Web Assets や Fingerprinting の流れを確認したい場合は、
こちらを見るのが一番確実です。
.NET 8 と .NET 10 の使い分け
既存の .NET 8 プロジェクトでは、
今すぐ .NET 10 相当の仕組みに寄せられないケースもあると思います。
その場合は前回の記事で紹介したような自前実装(内容ハッシュを使ったバージョン付与)が現実的です。
一方、新規の .NET 10 プロジェクトであれば、
まずは @Assets[...] と Static Web Assets の仕組みを前提にした方がシンプルです。
まとめ
.NET 10 テンプレートでは、静的ファイル参照が @Assets[...] に統一され、
配信時にはフィンガープリント付きファイル名へ解決されることを確認できました。
そのため新規開発では、.NET 8 のように ?v= 付与の仕組みを自前で用意する前に、
公式の Static Web Assets / Fingerprinting を前提に設計する方がシンプルです。
一方、既存プロジェクトでは現行構成を維持しながら段階的に寄せていく進め方が現実的です。
