先月 Blazor WebAssembly 3.2.0 がリリースされ、.NET Core 3.1.300 以降にアップデートすることで使用できるようになりました。
すでに Infragistics など著名な UI コンポーネントベンダーが対応しておりプロダクションレディな感じが漂っています。
WebAssembly 上に .NET CLR が実装され、Client と Server で共通の C# コードが動き、ASP.NET Core の要領でモダンな Web UI が作れるという、なんだかすごいフレームワークに興味津々で .NET Core を更新。
前回インストールして試してから1年近く経ってました。
ブログにあるようにコマンドを実行。
localhost:5001 にアクセスすると、素敵な Webアプリが表示されます。
プロジェクトのファイルを覗くと ASP.NET MVC の Razor 構文に似たテンプレートと C# コードでできてます。
開発の雰囲気を掴むために、このアプリに何かページを追加してみます。
GitHub に ASP.NET Core Blazer の Extension が公開されてます。
Canvas では 2D グラフィックスや WebGL のレンダリングがサポートされてます。
これを使って Canvas に描画する Page を追加しようってことで dotnet add package
を実行し Canvas 拡張を追加。
index.html に必要な JS ライブラリを追加。
<body> <app>Loading...</app> <div id="blazor-error-ui"> An unhandled error has occurred. <a href="" class="reload">Reload</a> <a class="dismiss">🗙</a> </div> <script src="_framework/blazor.webassembly.js"></script> <script src="_content/Blazor.Extensions.Canvas/blazor.extensions.canvas.js"></script> </body>
README に従って page (Canvas2D.razor) を追加
@page "/canvas2d" <h1>Canvas 2D</h1> <BECanvas Width="300" Height="400" @ref="_canvasReference" ></BECanvas> @code { @using Blazor.Extensions @using Blazor.Extensions.Canvas @using Blazor.Extensions.Canvas.Canvas2D private Canvas2DContext _context; protected BECanvasComponent _canvasReference; protected override async Task OnAfterRenderAsync(bool firstRender) { this._context = await this._canvasReference.CreateCanvas2DAsync(); await this._context.SetFillStyleAsync("green"); await this._context.FillRectAsync(10, 100, 100, 100); await this._context.SetFontAsync("48px serif"); await this._context.StrokeTextAsync("Hello Blazor!!!", 10, 100); } }
Navigation に page を追加。iconify のアイコンを指定できるようです。
Pepicons - 428 open source icons - Iconify
<div class="top-row pl-4 navbar navbar-dark"> <a class="navbar-brand" href="">BlazorApp1</a> <button class="navbar-toggler" @onclick="ToggleNavMenu"> <span class="navbar-toggler-icon"></span> </button> </div> <div class="@NavMenuCssClass" @onclick="ToggleNavMenu"> <ul class="nav flex-column"> : <li class="nav-item px-3"> <NavLink class="nav-link" href="canvas2d"> <span class="oi oi-map" aria-hidden="true"></span> Canvas 2D </NavLink> </li> </ul> </div> @code { private bool collapseNavMenu = true; private string NavMenuCssClass => collapseNavMenu ? "collapse" : null; private void ToggleNavMenu() { collapseNavMenu = !collapseNavMenu; } }
そして、dotnet run するとなんか出ました。
次に、WebGL グラフィックスを描画するサンプルです。こちらのテストプロジェクトからコードを持ってきました。
テストプロジェクト通りに razor ファイルと cs ファイルを分離して @inherits
を使って書いてみたのですが、cs 側で持ってる BECanvasComponent 型のフィールドを暗黙型変換できないというエラーが解消できませんでした。仕方なく Canvas 2D 同様 razor の @code ブロックに直書きしました。
なんか出ました。
C# と Razor のコードしか書いてないので、昔ながらの ASP.NET MVC 開発の感覚になります。React や Vue でおなじみの Live Reloading 機能はまだないらしく、ファイルを編集したら Ctrl-C で中断し再び dotnet run してブラウザ側を更新・・というちょっとめんどくさいワークフローになってます*1。
VS Code を当然使ってるわけですが、C# 拡張の他にデバッグのため JavaScript Debugger (Nightly) を導入することが推奨されています。
launch.json の設定をして、デバッグ用の Chrome が起動したのですが、僕の環境ではブレークポイントで実行が止まってくれませんでした。
今回のお試しコード
dotnetcore-study/BlazorApp1 at master · kondoumh/dotnetcore-study · GitHub
Blazor アプリのホスティングモデルの説明を読むとブラウザで完結する Blazor WebAssembly モデルとBlazor サーバーモデルがあり、今回見たのは Blazor WebAssembly の方です。Blazor サーバーは、ASP.NET Core アプリで WASM が実行され、ブラウザと SignalR で通信します。Blazor サーバーモデルではブラウザが WASM 対応している必要はないようです。Blazor WASM モデルだと規模が大きくなってくると、ダウンロードやローディングの時間が気になるレベルになりそうです。
今回初めて触りましたが完成度高い感じしました。WASM を基盤としているため Silverlight のようなプラグインが不要なのと、まんま ASP.NET のプログラミングモデルということで C#er には受け入れられやすい気がします。
*1:やり方を知らないだけという可能性はあります。