ASP.NET CoreプロジェクトにSvelteKitを組み込む
はじめに
ASP.NET CoreのフロントにSvelteを使いたいので、同一プロジェクト内でASP.NET Core Web APIとSvelteを扱えるようにする手順を示します。
ここでは、SvelteKit側はSPA(Single Page Application)の形態で利用することとします。
ASP.NET Core Web APIプロジェクトの作成
まずは、Visual StudioでASP.NET Core Web APIプロジェクトを作成します。
ここでは名前をSvelteAspNetApi
としました。
追加情報のダイアログは、以下のように設定しました。ここではコンテナのサポートは無効にしています。必要に応じて有効のチェックをつけてください。
SvelteKitのプロジェクトを追加
タームナルを開いて、作成したC#のプロジェクトのフォルダに移動します。ソリューションフォルダではなく、プロジェクトフォルダなので間違えないようにしてください。
ここでは、Svelteの公式ドキュメント通りにnpxコマンドを利用します。
-
まず、以下のコマンドを実行します。
npx sv create ClientApp
-
最初のテンプレートの選択では、「SvelteKit minimal」を選びます。
- 言語の選択では、JavaScriptを選択します。
- パッケージマネージャの選択では、npmを選択します。
※ それ以外の選択ではお好みの選択でOKです。
-
SvelteKitのプロジェクトが作成されたら、以下のようにタイプしてパッケージをインストールします。
cd ClientApp npm install npm install --save-dev @sveltejs/adapter-static
Visual Studio のソリューションエクスプローラーを開くと、ClientAppフォルダが追加されたのが確認できます。
svelte.config.jsの編集
ASP.NET CoreのホストでSvelteKitが動作するよう、svelte.config.jsを以下のように変更します。
svelte.config.jsは、ClientAppフォルダの直下にあります。
import adapter from '@sveltejs/adapter-static';
/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
adapter: adapter({
pages: '../wwwroot',
assets: '../wwwroot',
fallback: 'index.html'
})
}
};
export default config;
これは、Svelteのソースをビルドした際にファイルをASP.NET Coreのwwwrootフォルダに出力するためです。
Svelteの動作確認
ここで、Svelteのプロジェクトが動作するか確認してみます。
以下のコマンドをタイプします。
npm run build
正常に終了すれば、Visual StudioのソリューションエクスプローラーのSvelteAspNetApiプロジェクトにwwwrootフォルダが追加されているのが確認できます。
続いて、以下のコマンドを実行します。
npm run dev
以下のように表示されますので、http://localhost:5173/ にアクセスします。
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
➜ press h + enter to show help
以下のページが表示されればOkです。
q[Enter]
でnpm run devで動かしたプログラムを終了させます。
C#プロジェクトの変更
続いて、C#のプロジェクト側の対応をします。
Program.csを以下のように書き換えます。追加するのは+メークがついた3行です。
namespace SvelteAspNetApi;
public class Program {
public static void Main(string[] args) {
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment()) {
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
+ app.UseStaticFiles();
+ app.UseRouting();
app.UseAuthorization();
app.MapControllers();
+ app.MapFallbackToFile("index.html");
app.Run();
}
}
これで、Visual Studioからデバッグ実行してみます。
APIの動作確認をするSwaggerのページが表示されますが、ブラウザのURLを
https://localhost:7096/
に変えてみます。(ポート番号は環境によて異なるかもしれません)
これで、再度Svelteのページが表示されればOKです。
Svelteのプログラムが、ASP.NET Coreのホストで動作していることが確認できました。
API連携をしてみる
C#のWeatherForecastControllerを変更
まずは、APIのルーティングとSvelteのルーティングを区別するために、このプロジェクトではC#で作成するAPIは、
https://localhost:7096/api/....
のように必ず、apiで始まるようにします。
サンプルで作成されたWeatherForecast APIのコードを変更します。[Route]属性の引数を"api/[controller]"
に変更します。
using Microsoft.AspNetCore.Mvc;
namespace SvelteAspNetApi.Controllers;
[ApiController]
[Route("api/[controller]")]
public class WeatherForecastController : ControllerBase
Svelteに新規ページを追加
続いて、Svelte側にWeatherForecast APIを呼び出し、その結果を表示する新しいページを作成します。
以下のように、ClientApp/src/routes フォルダにweatherフォルダを作成し、その下に +page.svelteファイルを新規作成します。
+page.svelte を以下のように記述します。
<script>
import { onMount } from 'svelte';
let data = [];
onMount(async () => {
const response = await fetch('/api/WeatherForecast');
data = await response.json();
});
</script>
<h1>Data from API</h1>
{#each data as item}
<div>
<span>{item.date}</span>
<span>{item.temperatureC}</span>
<span>{item.temperatureF}</span>
<span>{item.summary}</span>
</div>
{/each}
このページでは、WeatherForecast APIを呼び出して、取得したデータを {#each}構文で表示しています。
続いて、ClientApp/src/routes/+page.svelteに以下のようなリンクタグを追加します。(これは、最初から存在する+page.svelteファイルです)
<div>
<a href="/weather">FetchData</a>
</div>
プロジェクトファイルを変更
このままですと、Svelte側に変更を加えるたびに、npm run build
を実行しなければなりません。C#側をビルドした時に、一緒のSvelteのソースをビルドできると便利です。
以下のコードをSvelteAspNetApi.csproj
ファイルに追加します。
<Target Name="NpmBuild" BeforeTargets="Build">
<Message Text="#Start npm run build" Importance="high" />
<RemoveDir Directories="wwwroot" />
<Exec Command="npm run build" WorkingDirectory="./ClientApp" />
</Target>
デバッグの初期URLを変更
デバッグするたびに、ブラウザのアドレス欄のURLを変更するのは面倒なので、初期URLを変更しSvelteのページが開くように変更します。
swaggerのページを開きたい場合は、直接以下のURLを開くこととします。
https://localhost:7096/swagger/index.html
プロジェクトのプロパティ画面を開き、デバッグ設定ダイアログを開き、URL欄をクリアします。
実行してみる
それでは、Visual Studio からデバッグ実行してみます。
最初に以下のページが表示されます
FetchDataのリンクをクリックすると、先ほど作成したページが表示されます。
APIを呼び出し、その結果を表示しているのを確認できます。
csprojファイルを編集し、発行にも対応させる
最後に、csprojファイルを編集して、発行にも対応させます。以下の行を追加してください。
<ItemGroup>
<Content Update="wwwroot\**" CopyToPublishDirectory="Never" />
<Content Update="ClientApp\**" CopyToPublishDirectory="Never" />
</ItemGroup>
<Target Name="CopyPublish" AfterTargets="Publish">
<Message Text="## Copy Vite build output" Importance="high" />
<Exec Command="xcopy /f /s /e /y $(ProjectDir)wwwroot\* $(PublishDir)\wwwroot" />
</Target>
これは、dotnetの発行の機能をそのまま利用すると、wwwrootにあるファイルをうまくコピーできないためです。
発行時の対象フォルダから除外して、xcopyコマンドで強制的にコピーしています。
Discussion