Blazor WebAssemblyのサンプルアプリをAWS環境へデプロイする
はじめに
最近WebAssemblyに興味があってちょこちょこ調べているのですが、.NETにもBlazor WebAssemblyというのがあって、.NET絶賛入門中でもあったのでちょっとどんなものなのか触ってみました。
今回は、チュートリアルにあるサンプルの実装とそれをAWS環境にデプロイするまでの流れをまとめたいと思います。
WebAssemblyとは
公式などに詳しく記載がされています。
- ブラウザ上で動作するオープンバイナリ標準です。
- 複数の言語で記述されたコードを、ネイティブ水準でブラウザ上で動作させることができます。
- WebAssemblyとしては異なるプラットフォーム間でのネイティブ水準での動作速度がでることを目標としています。
- C、C++、Rust 等の低水準言語にとって効果的なコンパイル対象となるように設計されています。
Blazor WebAssembly とは
WebAssemblyのオープンバイナリ標準を使って、.NETコードをブラウザ上で実行させることができます。
どのように実行されるかというと、まず.NETアセンブリにコンパイルされた.NETコードは.NETランタイムとともにブラウザにロードされます。
Blazor WebAssembly が.NETランタイムを初期化して、.NETアセンブリを構成します。
Blazor WebAssemblyはJavaScriptのサンドボックス内で実行され、DOMの操作やブラウザのAPIの呼び出しをJavaScriptを介して行います。
アプリはブラウザの機能に制限されることになりますが、JavaScriptを介してブラウザの全機能にアクセスすることができます。
開発環境の構築
今回はWSL2上で.NET CLI を使って開発していきます。
- OS : Ubuntu v18.04
- .NET CLI : .NET 5.0
- Editor : VSCode
まずは.NET CLIのinstallです。最初にパッケージリポジトリを追加します。
$ wget https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
$ sudo dpkg -i packages-microsoft-prod.deb
$ rm packages-microsoft-prod.deb
完了したらSDKをinstallします。
$ sudo apt-get update; \
sudo apt-get install -y apt-transport-https && \
sudo apt-get update && \
sudo apt-get install -y dotnet-sdk-5.0
バージョンが確認できればOKです。
$ dotnet --version
5.0.201
続いてVSCodeにC#の拡張機能 (C# for Visual Studio Code)をinstallします。
デバッグの設定も可能ですが、WSLやCodespacesでのデバッグはサポートされていません。サポートされている環境で動かす場合はDebug ASP.NET Core Blazor WebAssemblyを参考に設定してみてください。
サンプルアプリを作成する
CLIを使ってテンプレートを作成します。
dotnet new blazorwasm -o sample
-o
オプションはテンプレートプロジェクトを作成するフォルダ名になります。
sample
ディレクトリに移動して下記のコマンドを実行してみましょう。
$ dotnet run
localhost:5000
にアクセスすると下記のような画面が表示されるかと思います。
Ctrl + c
でアプリを停止できます。
出来上がったプロジェクトを覗いてみると、Razorコンポーネントが作成されているのがわかると思います。
ちなみに描画されるまでの流れとしては、
- ブラウザからリクエストが送信される
-
index.html
が返却される - アプリの初期化処理が走る。
- 初期化自体は
_framework/blazor.webassembly.js
を起点に行われています。
- 初期化自体は
- Blazorのルーターが読み込まれて、
index.razor
が表示される
といった感じです。
これらRazorコンポーネントはコンパイル時に.NETクラスに組み込まれてブラウザ上に描画されています。
Todoコンポーネントを追加する
これだけではさすがに味気ないので、作成したテンプレートプロジェクトにTodoコンポーネントを追加してみます。
sample
ディレクトリに移動してCLIを使ってrazorコンポーネントを追加します。
$ dotnet new razorcomponent -n Todo -o Pages
PagesディレクトリにTodo.razor
が作成されたのがわかるかと思います。
追加されたTodo.razor
にpageディレクティブを追加し、/todo
と相対URLを指定します。
@page "/todo"
<h3>Todo</h3>
@code {
}
今度はNavMenu.razor
にTodoコンポーネントへのリンクを追加します。
<li class="nav-item px-3">
<NavLink class="nav-link" href="todo">
<span class="oi oi-list-rich" aria-hidden="true"></span> Todo
</NavLink>
</li>
ちなみに、dotnet watch run
で起動した場合は、コンポーネントの変更を検知してコンパイル、テストの実行、デプロイが開始されるので、再起動などの必要がありません。
NavMenu.razor
にTodoコンポーネントのリンクを追加して保存をしたタイミングでサイドメニューにTodoのリンクが追加されるかと思います。
ここまでできたら次にTodoの処理を追加していきたいと思います。
まずTodoを管理するTodoItem
を追加します。sampleディレクトリ配下に追加します。
public class TodoItem
{
public string Title { get; set; }
}
追加したTodoItemのリストをTodo.razor
でバインドします。
@page "/todo"
<h3>Todo</h3>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
@code {
private List<TodoItem> todos = new();
}
次にtodoを登録するフォームとイベントを追加します。
@page "/todo"
<h3>Todo</h3>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
<input placeholder="Something todo" @bind="newTodo"/>
<button @onclick="AddTodo">Add todo</button>
@code {
private List<TodoItem> todos = new();
private string newTodo;
private void AddTodo()
{
if (!string.IsNullOrWhiteSpace(newTodo))
{
todos.Add(new TodoItem { Title = newTodo });
newTodo = string.Empty;
}
}
}
Todo.razor
を保存すると画面がリロードされて、Todoが追加できるようになっているかと思います。
これで一旦アプリの作成は終了です。
公式のチュートリアルではもう少し続きがあるのですが、何となく書き方がわかったところでデプロイ方法の説明に移っていきたいと思います。
AWS 環境へデプロイする
今回は自分が使い慣れたAWS環境へのデプロイ方法を説明します。やり方は色々あり、そもそもどうやって動かすかなども決めておく必要があります。
今回はできる限り楽をしたいと思い、最初はAppRunnerを使ってみたのですが、わざわざコンテナにWebサーバーを立てる必要もなくないかと思い、S3上に展開する方式にしました。
最初は手動でS3にアップロードして試していたのですが、AWS .NET deployment tool でS3上に簡単に展開できることを知ったので、こいつを使ったデプロイの方法を説明します。
AWS .NET deployment tool が動く環境を整える
基本的にはReadmeに従って進めれば何も問題ありません。
事前に必要なものとしては、
- AWS アカウントの作成とcredentialの設定
- .NET Core 3.1 以上
- Node.js 10.3 以上
- 内部的にCDKを使っているため
です。
ローカルに直にこの環境を整えるよりVSCode のRemote Developmentを使った方が楽かと思い、以下のような .devcontainer/Dockerfile
を使って実行しました。
FROM centos:7
WORKDIR /tmp
RUN yum install -y unzip less zip && \
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" && \
unzip awscliv2.zip && \
./aws/install
RUN yum install -y https://rpm.nodesource.com/pub_14.x/el/7/x86_64/nodesource-release-el7-1.noarch.rpm && \
yum install -y nodejs
RUN rpm -Uvh --force https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm && \
yum install -y dotnet-sdk-5.0
RUN dotnet tool install --global aws.deploy.cli
ENV AWS_ACCESS_KEY_ID=<set your aws access key>
ENV AWS_SECRET_ACCESS_KEY=<set your secret access key>
ENV AWS_DEFAULT_REGION=ap-northeast-1
ちなみに最初はAWS CLI のインストールを省くためにAmazonLinuxをベースにしようと思ったのですが、AWS .NET deployment toolがうまく動かなかったのでCent7にしました。
デプロイする
環境が出来上がってしまえばあとはコマンドを1回実行するだけです。
.csproj
ファイルがあるディレクトリに移動し下記コマンドを実行します。
$ dotnet aws deploy
コマンドを実行するとRegion選択を迫られますのでお好きなregionを選択ください。
このあとも色々聞かれますがデフォルトを選択すればOKです。
完了するとエンドポイントのURLが表示されるのでアクセスすると、作成したサンプルアプリが表示されるかと思います。
これで一通りの説明は以上になります。
後片付け
最後に、そのまま放置もまずいので後片付けだけして終了です。
まずdeployment toolで作成したstackの名前を確認します。
$ dotnet aws list-deployments
今回の場合は sample
という名前になっていたかと思います。
この名前を指定して削除コマンドを実行したら完了です。
$ dotnet aws delete-deployment sample
コンソールから確認してもstackやbucketが削除されているのが確認できると思います。
まとめ
deployment toolをinstallするのが若干面倒かもしれませんが、それさえできてしまえば、作成からデプロイまで思ってた以上に簡単にできた印象です。
ドメインとか証明書の設定もdeployment toolでできるのかなど、まだわからないこともあるので、そこはこれから調べていきたいと思います。
参照
- https://webassembly.org/
- https://docs.microsoft.com/ja-jp/learn/modules/build-blazor-webassembly-visual-studio-code/1-introduction
- https://docs.microsoft.com/en-us/aspnet/core/blazor/?view=aspnetcore-5.0#blazor-webassembly
- https://aws.amazon.com/jp/blogs/developer/reimagining-the-aws-net-deployment-experience/
Discussion