Native DependenciesのサポートでBlazor WebAssemblyはどうなるか

この記事は [Qiita Advent Calendar 2021 Blazor](https://qiita.com/advent-calendar/2021/blazor) の2日目の記事です。

.NET 6.0 が無事GAされ数多くの新機能が追加されました（[日本マイクロソフトさんのPR Advent Calendar](https://qiita.com/advent-calendar/2021/microsoft) で他の方が新機能だったり嬉しい機能について熱く語ってくれるはずなのでこちらもどうぞ）。

その中で Blazor に関して私が一番アツいと感じた変更が [Blazor WebAssemblyのネイティブ依存サポート](https://docs.microsoft.com/en-us/aspnet/core/blazor/webassembly-native-dependencies?view=aspnetcore-6.0&WT.mc_id=DT-MVP-5002987) です。

~~どの様な仕組みで行われているのかだったり歴史みたいのは別の記事かコミケの記事で書こうかな…~~

## これまでのBlazor WebAssembly

.NET 6.0 以前の Blazor WebAssembly ではネイティブ依存のあるライブラリを使用することが出来ませんでした（https://github.com/dotnet/aspnetcore/issues/8158 ）。
例えば画像処理に多く使われているOpenCVみたいなライブラリがそれに該当します。

そのためデスクトップ上で動作するアプリケーションをそのままブラウザ上で動作させることはプロジェクトによっては困難なケースがありました。
その場合は C# や F# で同様の処理を行うことの出来るライブラリに移行する（OpenCVの代替としてImageSharpとか）みたいな処置が行われていたことでしょう。

## これからのBlazor WebAssembly

しかし .NET 6.0 時代の Blazor WebAssembly ではネイティブの依存があるライブラリでも、ブラウザ上で動作させることが可能となりました（条件あり）。
これによりデスクトップ上で動作していたアプリケーションの UI を Blazor や JS で記述し、ロジックをそのままブラウザ上で動作させるみたいなことが現実となりました。

UIに関しては 1日目の @kimuradesu さんの [Blazorプロジェクトのテンプレートについて](https://qiita.com/kimuradesu/items/84535ffdc376dcae862c#%E3%82%B5%E3%83%BC%E3%83%89%E3%83%91%E3%83%BC%E3%83%86%E3%82%A3%E3%83%BC%E3%81%AEblazor%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88) のサードパーティの Blazor テンプレートとかを参考にかっこいいのも使えそうです :+1:
また React で UI を構築して、Blazor 側のロジックを使う例は

https://qiita.com/yamachu/items/8bc6e9cab5f2ffc53658

昨年の Advent Calendar 1日目 の記事をどうぞ。

またネタではありますが、Rust で作ったライブラリを Blazor WebAssembly 上で動かす、みたいな異色の融合みたいのも wasm を介することで可能となっています。

https://github.com/yamachu/BlazorWebAssemblyRustBindingSample

## しかし現状は

さて条件ありと書いたのはそのままの意味で、ネイティブ依存を持つライブラリ側が Blazor WebAssembly 上で動作するように対応している必要があるからです。
執筆時点で対応が確認されているメジャーなライブラリは [Skia.Sharp](https://github.com/mono/SkiaSharp) ぐらいしか観測されず、他は私が対応させた日本語TTSの [OpenJTalk ラッパー](https://www.nuget.org/packages/SharpOpenJTalk) だったり、音声分析合成ライブラリの [World ラッパー](https://www.nuget.org/packages/DotnetWorld/) ぐらいだったりします。

[GitHub上での検索](https://github.com/search?l=XML&o=desc&q=NativeFileReference&s=indexed&type=Code) でも執筆時点で "NativeFileReference" の文字が含まれた XML は 33 件とまだまだ対応が進んでいない状況です。
単純にまだ GA されてから日が浅いのと、十分にライブラリのテストを行うのが難しいなど、ノウハウがまだ溜まっていないことが影響していそうです。

そのため自分が使いたいライブラリがある場合は自分で Blazor WebAssembly 対応を行う必要があります。

実際に自分が対応を行うために準備したことなどは

https://teitoku-window.hatenablog.com/entry/2021/11/08/234722

こちらに記載しましたのでぜひともご覧ください。
基本的には Emscripten でビルドを通すことが出来れば Blazor WebAssembly 対応に大幅に近づきます。

またもう一例として OpenCVSharp の Blazor WebAssembly も現在行っています。

https://github.com/yamachu/opencvsharp/pull/1

ライブラリのロード周りや、[コールバックなど、サポートされていない機能](https://docs.microsoft.com/en-us/aspnet/core/blazor/webassembly-native-dependencies?view=aspnetcore-6.0&WT.mc_id=DT-MVP-5002987#c-managed-method-callbacks)を Managed 側で呼んでいるとクラッシュするなどのハマりどころも多かったりしますが、ぜひとも上記の記事やPRを参考に挑戦してみてください。

## おわりに

ネイティブ依存のサポートが行われるまで、行われてからの Blazor WebAssembly がどうであるか、どうなるかと、それを取り巻く環境について簡単に述べました。

実際に Blazor WebAssembly 対応に挑戦しようとなると、例えば C/C++ のプロジェクトのビルド方法だったり、P/Invoke 周りの知識だったりが必要でなかなかハードルが高いのは事実ではあります。
しかし多くの人が挑戦しその知見が共有されれば対応ライブラリも増えたりみたいな未来がやってくると思うので、ぜひ挑戦してみてください。

テスト周りが一番求められるところではあるので、その辺りをガンガン掘り進められるといいな…