BETA

Razor構文と生成されるコードのメモ+F#に関するおまけ

投稿日:2019-08-23
最終更新:2019-08-23

ビルド時、.razorのファイルからなんか.csファイルが自動生成されるっぽいけど、どんなファイルを生成してるの? というのが気になって色々いじってみたメモです。

普段はプロジェクトフォルダ以下のobj/Debug/netstandard2.0/Razor/に生成されています。

razor構文から自動生成されるコード

基本的にはMicrosoft.AspNetCore.Components.ComponentBaseクラスを継承し、BuildRenderTreeメソッドを呼ぶクラスで構成されています。

App.razor

namespace Blazorwasm  
{  
    public class App : Microsoft.AspNetCore.Components.ComponentBase  
    {  

        protected override void BuildRenderTree(Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder)  
        {  
            builder.OpenComponent<Microsoft.AspNetCore.Components.Routing.Router>(0);  
            builder.AddAttribute(1, "AppAssembly",   
                        Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck(typeof(Program).Assembly ));  
            builder.AddAttribute(2, "NotFoundContent", (Microsoft.AspNetCore.Components.RenderFragment)((builder2) => {  
                        builder2.AddMarkupContent(3, "\r\n        ");  
                        builder2.AddMarkupContent(4, "<p>Sorry, there\'s nothing at this address.</p>\r\n    ");  
            }));  
            builder.CloseComponent();  
        }  
    }  
}  

AppクラスはMainメソッド内のRun()がコールされた内部でインスタンス化されます。
恐らく、ここでindex.html<app>タグ内のDOMを挿げ替えているのでしょう。
rootに設定しようとすると無限ループになるようです。

Index.razor

namespace Blazorwasm.Pages  
{  
    [Microsoft.AspNetCore.Components.LayoutAttribute(typeof(MainLayout))]  
    [Microsoft.AspNetCore.Components.RouteAttribute("/")]  
    public class Index : Microsoft.AspNetCore.Components.ComponentBase  
    {  
        protected override void BuildRenderTree(Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder)  
        {  
            builder.AddMarkupContent(0, "<h1>Hello, world!</h1>\r\n\r\nWelcome to your new app.\r\n\r\n");  
            builder.OpenComponent<BlazorWasm.Shared.SurveyPrompt>(1);  
            builder.AddAttribute(2, "Title", "How is Blazor working for you?");  
            builder.CloseComponent();  
        }  
    }  
}  

[Microsoft.AspNetCore.Components.RouteAttribute("/")]がrazor構文上の@page "/"にあたるようです。
OpenComponentで指定したクラスのプロパティ名をAddAttributeの第2引数で、第3引数で値を指定しています。
基本的に書き方はJavaScriptのものと似ている(良く知っているわけではないですが)のではないかなという印象です。

実際のIndex.razorは以下の通りです。

@page "/"  

<h1>Hello, world!</h1>  

Welcome to your new app.  

<SurveyPrompt Title="How is Blazor working for you?" />  

たまにVisual Studioがエラーを吐く時に上手くフォルダ内のデータが削除できていなかったっぽいことや、razorファイルをリネームしたときにビルド時のエラーが消えなかった際になんかコードが吐かれていることを知りました。

今回この記事を書こうと思った動機はもっと別のところにあります。

F♯でBlazorを動かす

F#でWebAssemblyならBoleroというものがありますが、やはりrazorっぽくHTMLとコードを合わせて書きたいのと、Boleroのサンプルプロジェクトの記述がMain.fsに集約されていて辛かった部分がありました。.razorから.csを自動生成する逆をやるならどうやるのか知りたくて色々やっていたところ、何とか実行できるところまで行けましたというご報告です。

https://github.com/ethansan3/Flazor
ボタンを押すとインクリメントするだけですが、一応これで動きますというのをGitHubにメモ程度に置いてあります。
結局、namespaceはrecを付けたり、変数はmutableにしないとダメなところがありましたけど "thinking functionally" が足りないのでしょうか。

F#でHTMLやCSSをパースするのにはFsharp.Dataというライブラリがあったので、これを使うと例えば.frazorのようなHTMLやCSSとF#のコードを混ぜて書けるファイル構造のものを解析して.fsを自動生成するということができなくはなさそう(できるとは言っていない)。

まとめ

Blazorはいいぞ。そして.NET Coreもでしょうか。
Raspberry PI 3B+ + Ubuntu Server + nginx でBlazor(wasm)を動かせたのでそれも一応記録しておきたい。
小さな会社のシステム作って動かすならすごく手軽じゃあないでしょうか。

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

@hiro3の技術ブログ

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる
技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
or 外部アカウントではじめる
10秒で技術ブログが作れます!