Posted at

WebAssemblyによる同一言語でのサーバ&クライアント開発


WebAssemblyは速い

WebAssembly Advent Calendar 2018を見つけたので、早速記事を書くことにしました。さて、WebAssemblyですが、これは何のための技術でしょうか?Wikipediaで調べると「クライアントで動く低級言語」というフレーズが出てきます。名前もアセンブリというぐらいだし、最初に思いつくのは速度のアドバンテージでしょう。QittaにもなぜWebAssemblyはasm.jsより速いのかという記事で速い理由が述べられています。しかし今回僕がWebAssemblyの記事を書こうと思ったのはこの速度面によるメリットの説明ではありません。


アセンブリ言語は高級言語で書く

実際高速で動くアセンブリ言語ですが、では現在普通の開発においてアセンブリ言語で書くことはあるでしょうか?僕は元ゲームプログラムで20年近くゲームを作って来ましたが、アセンブリ言語で書いたことは殆どありませんでした。本当に一部に使ったことはありますが95%(もっと?)は高級言語で書いていました。同じようにWebAssemblyも高級言語で書くことが当たり前になると思います。ゲームの場合現状はC++以外の選択肢は殆どありませんが、WebAssemblyは恐らくもっと幅広い言語で書けるようになると思います。


高級言語によるWebAssebmlyフレームワーク

さて、では現状で高級言語で書けてWeb開発できるようなフレームワークはあるでしょうか?2018年現在、サイトのトップにexperimental(実験的)とはついていますが、C#でSingle Page Applicationを作ることができるBlazorというプロジェクトがあります。実際に使ってみて、正直まだ実験段階とは言え、近い将来のWeb開発で主流となっていく考え方だという印象を受けました。というわけで、今回は高級言語によるWebAssebmlyフレームワークBlazorについて書こうと思います。


僕の開発環境

その前に、僕自身が開発している環境について述べます。最初はASP.NET MVCでサーバーサイドをC#で書いて、クライアントはRazorを使ってC#で書いていました。あとは必要な部分のみTypeScriptです。これで自分のサービスをα版まで作りました。そこから技術の見直しをして、サーバーはASP.NET Web APIでC#。クライアントはVue.jsにしました。この時点でがっつりJSライブラリを使うのは初めてでした。JSの進化の速さへの対応や必要な知識の膨大さなどになかなか苦労しました。そしてVueからBlazorに乗り換え中です。


2つの言語を使うデメリット

そもそも一つのアプリならサーバとクライアントでほぼ同じデータを扱います。にも拘らず、そのコードを使いまわすことが出来ない、言語仕様の違う2つの定義を書かないといけない。これが結構苦痛でした。その後も同じようなコードをC#側で書いたのにまたそれをJSに移植しなといけないのかと思うことがありました。自分のメインで使っている言語で書けないことで、ストレスを感じる。これはどの言語でサーバを書いている人でも多かれ少なかれ思うことではないでしょうか?


同一言語でサーバ&クライアントが書ける

さて、改めて高級言語でWebAssemblyを使えると何が良いのか。この一番のメリットはサーバとクライアントで同じ言語を使えること。もともとこれだけが理由でBlazorに飛びつきました。そして実際にBlazorを使ってみると、クライアントのコードを書くのにサーバーと同じ言語で考えれば良い。スイッチングがないだけで、こうも快適かと思えました。JSで書くのが少し辛くなってモチベーションが下がっていたので、Blazorを使って同一言語で書けることがとても楽しくなりました。


Server,Client,Sharedの切り分け

もう少し具体的に説明すると、Blazorはテンプレートからプロジェクトを作ると3つのプロジェクトに分けられます。Server,Client,Sharedです。名前で分かると思いますが、Serverがサーバーサイド、Clientがクライアントサイド、そしてサーバーとクライアントで共通で使う部分がSharedです。このSharedの存在がとても大きいです。モデルは基本Sharedに定義します。またサーバーやクライアントで出てくるアルゴリズムの部分もなるべく抜き出してSharedに書きます。


Sharedへの移行

これは僕がJSに慣れてないだけかもしれませんが、JSで書いているときはViewでアルゴリズムも考えていました。もう少し使い慣れていけばJSでもMVC的な切り分けをしていくのだと思いますが、どうしてもhtmlから呼ぶ単一のJSの中でやってしまいがちだと思います。Blazorで作っていくと自然とViewはClient、アルゴリズムはSharedに分けて作るようになっていました。Viewがどんどん薄くなってプログラムの実体がSharedに集約していきます。基本Sharedは他に依存しないのでテストを書くのも容易です。


ClientはSPA

Blazorは今までJSでしか書けなかった動的なhtmlをC#で書くことが出来ます。データの連動はbindingです。キックのタイミングはイベントです。イベントでプロパティに値を入れれば描画は追従してくれます。チェックボックスなどは双方向。ページの内容をまとめたい時はComponetを使います。コンポーネント最高です!もうお判りでしょうが、JSライブラリのSPAと殆ど違いはありません。ゆえに現状のJSのノウハウはかなり近い状態で使えると思います。逆に言えばSPAの知識ゼロでいきなりBlazorに入るのは難しいようにも感じます。


WebAssemblyによる同一言語でのサーバ&クライアント開発

というわけで、まとめです。WebAssemblyのメリットの一つは、WebAssemblyを使用して同一言語でのサーバ&クライアント開発出来ることです。その際、サーバとクライアントの共通部分はなるべく切り出して、モデルの定義やテストも共通部分で行います。ViewはSPAが基本で、JSライブラリと同等の開発が出来る。今後、WebAssemblyを使ったフレームワークでの開発スタイルは多くの言語でこの形になっていくんじゃないかと思います。いろんな言語で単一言語でのサーバ&クライアント開発出来るWebAssemblyの未来楽しみですね!