🧩

vite-plugin-dotnet-wasm で始める .NET WebAssembly + Webフロントエンド実践

に公開

フロントエンドで複雑なロジックを扱うとき、JavaScript(TypeScript)だけで押し切るか、バックエンドに逃がすか、はたまた他の言語で WebAssembly化するかの選択肢があると思います。
その中の WebAssembly化の選択肢を取った場合、既に C# の資産があるなら、ブラウザ上で .NET WebAssembly として動かすということが出来るのです。

本記事では、vite-plugin-dotnet-wasm を使って、Vite の開発体験を保ちながら .NET WebAssembly を組み込む方法をご紹介します。

https://github.com/yamachu/vite-plugin-dotnet-wasm

.NET WebAssembly がなぜ Webフロントエンドで有効なのか

.NET WebAssembly は、既存の .NET のコードをブラウザ上で直接動かせる技術です。リッチな型表現ができる C# でロジックを記述でき、豊富な .NET 資産を活用でき、wasm 対応済みのライブラリであれば比較的容易にそのままフロントエンドで使えます。

重要なのは、JavaScript を置き換えることではなく、フロントエンドに .NET を持ち込んで共存させることです。UI は JavaScript や TypeScript でそのまま組み立て、複雑なロジックは C# に持たせる。複数の言語と技術をブラウザの中で自然に共存させられるのが、.NET WebAssembly の面白さです。

ただし、素の .NET WebAssembly を既存のフロントエンド開発フローに組み込むには、ビルドの連携・成果物の配置・ランタイムファイルの配信など、いくつか手作業の配線が必要になります。そこを整えるのが、このプラグインです。

vite-plugin-dotnet-wasm が解決する課題

vite-plugin-dotnet-wasm は、.NET WebAssembly をブラウザで動かすための面倒な作業を、Vite の開発体験に寄せて扱えるようにするためのプラグインです。.NET WebAssembly 自体は .NET が提供する技術ですが、それを既存のフロントエンド開発に自然に組み込むところにはまだ課題があると感じています。このプラグインは、そのギャップを埋める役割を持っています。

たとえば開発時には、フロントエンドの dev server と別に .NET 側のビルドも追従させる必要があります。本番ビルドでは、.NET WebAssembly の成果物である _framework 配下のファイルを、Vite の出力物と一緒に正しく配置しなければなりません。import パスや静的ファイルの扱い、また base パスの対応など、素朴にコピーするだけでは解決できず少し不便です。こうした点をまとめて吸収し、Vite のプラグインとして使える形にしているのが、このプロダクトというわけです。

設定は簡単

導入はかなりシンプルです。Vite の設定にプラグインを追加し、対象となる .NET WebAssembly プロジェクトの csproj を指定します。

$ pnpm add -D @yamachu/vite-plugin-dotnet-wasm
import { defineConfig } from "vite";
import dotnetWasm from "@yamachu/vite-plugin-dotnet-wasm";

export default defineConfig({
  plugins: [
    dotnetWasm({
      /** Required */
      projectPath: "./DotNetProject/MyWasmApp.csproj",
      /** Optional */
      configuration: "Release",
      dotnetBuildArgs: [/* Additional arguments for dotnet build, default: undefined */],
      watch: true, // Enable watch mode (dotnet watch build), if you want to build once and without watching .NET files changes, set to false
    }),
  ],
});

設定としてまず重要なのは、.NET 側のプロジェクトを明示する projectPath だけです。これによって、Vite 側から .NET WebAssembly プロジェクトのビルドや成果物の取り扱いを連携できるようになります。必要に応じて Release と Debug の切り替えや、追加の dotnet build 引数、watch の有無も調整できます。なお、dotnetBuildArgs などオプション引数周りはまだ十分にテストできていない部分があります。何か問題があれば Issue や PullRequest をお待ちしています。

ちなみにこのプラグインは Vite v7 時代に作成していたのですが、v8 でも動作しました。安心して最新の環境でお使いいただけます。

デモ

上記プラグインを使用したアプリケーションがこちらです。

https://yamachu.github.io/vite-plugin-dotnet-wasm/

上記のページでは、JavaScript と C# がブラウザ上で自然にイベントなどをやりとりしているのが確認できます。サンプルでは、JavaScript 側で .NET ランタイムを立ち上げ、C# で公開したメソッドを呼び出しています。一方で、C# 側も JSImport を使って JavaScript の関数を取り込み、画面表示を更新しています。

つまり、UI の組み立てやイベント処理は普段通りフロントエンド側に残しつつ、状態管理やロジックの一部を C# に寄せるみたいなことが実現しているのです。単に .NET がブラウザで動く、ではなく、既存のフロントエンドの流れの中に .NET を挿し込めるのがおもしろポイントです。 dotnetWasm.jsProgram.cs を見ることで、実際にどのようにやり取りしているのかを確認できます。

おわりに

vite-plugin-dotnet-wasm が提供しているのは、.NET WebAssembly を動かす機能そのものだけではありません。Vite での開発体験を保ったまま、ブラウザのフロントエンドに C# を持ち込めることをサポートしているのです。

これを見て .NET WebAssembly に興味を持ち、試してみようと思う人が増えたら嬉しいです。

…と、めちゃ推してはいますが、どんな画面や Webフロントエンドアプリケーションに向くわけではありません。初期ロードを極限まで軽くしたいページや、ほぼ静的表示だけで済む画面では、導入コストに対して得られるものが小さい場合もあります。
例えば業務アプリだったり、自分用のユーティリティアプリとかに一旦試してみる、とかもいいかもですね。

Discussion