ついに Blazor にも Hot Reload がやってくる! - しかもタダモノではないw

# はじめに - "Blazor" って何?

"Blazor" (ブレイザー) とは、C# でシングルページ Web アプリケーション (いわゆる SPA) を実装することのできるフレームワークおよびランタイムです (下記は公式サイト)。

https://blazor.net/

Blazor は、React や Vue、Anguar といった JavaScript でコーディングするフレームワーク/ライブラリに相当します。
ただし、言語やパッケージシステムが JavaScript (TypeScript) や npm ではなく、**C#** と NuGet となります。

Blazor にはその実行形態によって "Blazor Server" と "Blazor WebAssembly" の2形態があります。 ("Blazor Mobile Binding" とかその他の Blazor の名の付くものは割愛)。
とりわけ "Blazor WebAssembly" は、C# ソースコードを JavaScript にトランスパイルする**のではなく**、**コンパイル後の .dll がそのままブラウザ上で動く**のが面白いところです。
(ブラウザ内の WebAssembly 上で、.NET のインタープリタが実行することで実現されている)

# Blazor には Hot Reload はなかった...

さて、そんな、刺さる人には刺さる Blazor ですが (参考: ["Blazor をお勧めできる人は誰か?"](https://qiita.com/jsakamoto/items/52c5ef52fc5ccebaae1f))、他の JavaScript 製 SPA フレームワークでは一般的な "Hot Reload" (あるいはまた、Live Reload、Hot Module Replacement などと呼ばれるような) の機能がありませんでした。

Hot Reload、つまり、アプリケーションのソースコードやマークアップを変更・保存したときに、開発実行中の Web アプリケーションを毎回全体をリロードすることなく、変更がブラウザ上に反映されるという、開発者向けの便利機能ですね。

もちろん、近代の SPA フレームワークということで、Blazor の「将来実現したいリスト」には当初から Hot Reload も載っていました。

しかしながら本稿執筆現在、.NET Core 3 から .NET 5 に至るまで、Blazor の Hot Reload 機能は実現に至っていません。
(独自の実装・技術によって、Hot Reload 機能を提供している 3rd パーティ製品はあるようです)

# NDC Manchester 2021

さてところで、つい先日、2021/3/23～25 (現地時間) の日程で、"NDC Manchester 2021" というソフトウェア開発者向けのイベント (今回はオンライン) が開催されました。

https://ndcmanchester.com/

NDC は、Blazor の生みの親、Steve Sanderson 氏による、初めて Blazor が世に広くお披露目されたイベント (NDC Oslo, 2019年) でした。

Steve Sanderson 氏は、NDC のスピーカとして度々登壇されていますが、今回の NDC Manchester 2021 でも再び登壇。

https://ndcmanchester.com/agenda/blazor-in-2021/ddb877bffe41

"Blazor in 2021" と題してセッショントークされていました。

https://twitter.com/stevensanderson/status/1375007550861623296

NDC Manchester 2021 は録画が公開されているので、自分も数日遅れで氏のセッション録画を視聴しました。
 (下記 YouTube URL。氏のセッションは、4時間21分程から。下記リンクで、氏のセッション時間からの再生になります。)

<iframe width="560" height="315" src="https://www.youtube.com/embed/5NqXBFn9v20?start=15632" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

すると、どうでしょう、
**なんと、.NET 6 Preview の Blazor における Hot Reload のプロトタイプが実際にライブでデモンストレーションされているではないですかー!**


ついに、**念願の Hot Reload が、.NET 6 とともに、Blazor にもやってくるようです!**

素晴らしい!

# Blazor での Hot Reload - 状態管理は...?

ここまで「おおー！」と盛り上がりながらセッション録画を観ていたのですが、あらたな疑問が湧いてきます。

「Hot Reload 発生時、コンポーネントの "状態" は失われてしまうのだろうか...」

コンポーネントの "状態" とは、例えば Blazor プログラマならおなじみ (?) の、カウンターページを考えてみましょう。

カウンターページは下記のような .razor ソースコードになりますが、ここでいう状態とは、"currentCount" フィールド変数に格納されている値、ということになります。

```csharp
<p>Current Count: @currentCount</p>
<button @onclick="IncrementCount">Click me</button>

@code {
  int currentCount = 0; // 👈 ここでいうところの "状態"
  
  void IncrementCount() {
    this.currentCount += 1;
  }
}
```

ここで、カウンタの増分を 1 から 100 に変更したとします。

```csharp
...
@code {
  int currentCount = 0;
  
  void IncrementCount() {
    this.currentCount += 100; // 👈 ここを "+= 1" から "+= 100" に変更
  }
}
```

このように .razor ファイルを書き換えて保存すると、Hot Reload が発生しますよね。

Hot Reload が発生すると、この "currentCount" フィールド変数に格納されている値は失われ、0 に戻ってしまうんじゃないかな、と思っていたのですが...

```csharp
...
@code {
  // 👇 Hot Reload が発生したら、0 に戻ってしまうのでは...?
  int currentCount = 0;
  
  void IncrementCount() {
    this.currentCount += 100;
  }
}
```

ところが、なんと、**Hot Reload が発生しても、"currentCount" フィールド変数の値は 0 に戻ることなく維持されている**ではないですか!

もちろん、コードの変更は反映されているので、Hot Reload 後に "Click me" ボタンをクリックすると、(その時点でのカウンタ値から) 100 ずつカウンタ値に加算されるようになっています!

これ、状態保存用のサービスとか使っていないわけですよ。
ただのフィールド変数なわけですよ。

**開発者が Hot Reload のために既存コードを改修しなくても、状態維持された Hot Reload 機能が手に入る**ってことですよね?

これって凄くないですかww

# Blazor の Hot Reload は、そもそも .NET 6 としてのコア機能?

なんでこんな芸当ができるのか、自分にはその理解を超えておりますが、そもそもこの Hot Reload は、Blazor のようなアプリケーション/ライブラリのレイヤーでは実装してないっぽいのがポイントなのかなー、と想像しています。

というのも、2021/3/11 にブログで発表のあった次世代 .NET バージョン、.NET 6 の Preview 2 のお知らせにて、「.NET 6 では、Hot Reload 実現も大きなテーマである」として言及されていたからです。

https://devblogs.microsoft.com/dotnet/announcing-net-6-preview-2/

つまり、.NET の CLR のレベルから Hot Reload 実現のための仕組み作りをしているのであれば、既存コードそのままでも状態維持された Hot Reload を実現することもできるのだろう、と思うわけです。

# 超絶期待大!

というわけで、たしか、今年 2021 年の 11月頃が .NET 6 のリリース予定と聞いた覚えがありますが、つまりはその頃には、Blazor での Hot Reload も利用できるようになっているかもしれない、ってことですよね?

これは楽しみです!

ただ、NDC Manchester 2021 のデモで使われていた Blazor は、 Blazor Server であって、Blazor WebAssembly ではないんですよね...

Blazor WebAssembly は、ブラウザ上での動作ということで、また違った困難があると思うので、果たして Hot Reload が Blazor WebAssembly でも実現されるのかどうか、気懸かりではあります。

とはいえ、まぁ、万が一、Blazor WebAssembly に Hot Reload が来てくれなくても、主立った開発中は Blazor Server として Hot Reload の恩恵に預かりながら開発作業を進めて、要所要所、そしてリリースは Blazor WebAssembly とする、といったハイブリッド戦略でもできなくはないですね!
(実際、今でも、Visual Studio デバッガによるデバッグ作業の効率化のために、このようなハイブリッド方式の開発をすることもあります)

_[2021/03/28 追記]_
Blazor WebAssembly でも Hot Reload できそうな予感! Steve Sanderson 氏が Twitter 上に「Blazor WebAssembly でも状態維持した Hot Reload が動いた (とりあえずレベルだけど)」と、投稿してました!

https://twitter.com/stevensanderson/status/1331669721041805314

_[2021/03/28 追記ここまで]_

そうそう、もちろんのことながら、Hot Reload は CSS (分離CSS) の変更にも対応しているようです。

自分は、Blzor の Hot Reload が待ちきれなくて、せめて CSS だけでも Hot Reload (Live Reload) できるようにしたく、独自の実装を公開しましたが (下記参照)、

https://qiita.com/jsakamoto/items/cbab6e9ec105711a0bb8

.NET 6 がリリースされた暁には、この CSS ライブリロードサーバーも、晴れてお払い箱にできることでしょうw

.NET 6、そして Hot Reload が実現されれば、より効率的な開発作業ができるようになり、開発者に優しいのはもちろんのこと、結果として、リリースされる製品の品質向上や機能拡充などに寄与することでしょう。

.NET 6 や Blazor の開発に関わっている各位に感謝しつつ、.NET 6 そして Hot Reload のリリースを楽しみに待ちたいと思います!

_Learn, Practice, Share!_