BlazorのComponentを別プロジェクト(RazorClassLibrary)へ切り分けた際、
Blazorから別プロジェクトの静的リソースへアクセスすることが出来ずにハマったので、それの件について記録します。
SolutionとProjectの作成
以下のコマンドでBlazorApp
と、Component役のMyComponent
を作成します。
※Component役プロジェクトはrazorclasslib
で生成します。
dotnet new sln -o BlazorComponentSample cd BlazorComponentSample dotnet new blazorserver -o BlazorApp dotnet new razorclasslib -o MyComponent dotnet add .\BlazorApp\BlazorApp.csproj reference .\MyComponent\MyComponent.csproj dotnet sln .\BlazorComponentSample.sln add BlazorApp MyComponent
MyComponentの作成
MyComponent.csproj
のTargetFramework
バージョンを上げておきます。
<Project Sdk="Microsoft.NET.Sdk.Razor"> <PropertyGroup> - <TargetFramework>netstandard2.0</TargetFramework> + <TargetFramework>netstandard2.1</TargetFramework> <RazorLangVersion>3.0</RazorLangVersion> </PropertyGroup> </Project>
MyComponent
ではCSSフレームワークにBulma
を使用することにします。
Bulmaはnpmで入れたいので、MyComponentフォルダ
以下にpackage.json
を作成します。
package.json
{ "version": "1.0.0", "name": "blazor", "private": true }
以下のコマンドでBulma
をインストールします。
MyComponentフォルダ
以下にnode_moduleフォルダ
が生成されます。
npm install --save-dev Bulma
ビルド時にnode_module
フォルダからwwwroot
フォルダへBulma
のcssをコピーする設定を行います。
以下のコマンドで、BuildBundlerMinifier
をインストールします。
dotnet add package BuildBundlerMinifier
MyComponentフォルダ
にbundleconfig.json
を作成します。
[ { "outputFileName": "wwwroot/lib/bulma/css/bulma.min.css", "inputFiles": ["node_modules/bulma/css/bulma.min.css"], "minify": { "enabled": false, "renameLocals": true } } ]
これでビルド時にファイルのバンドルが行われるようになりました。
試しにdotnet build
でビルドしてみましょう。wwwroot
以下にlib/bulma/css/bulma.min.css
があれば成功です。
続いてComponent.razorの編集を行います。
呼び元からName
, SNSId
, Content
をParameterとして受け取り、表示するだけです。
<div class="box"> <article class="media"> <div class="media-left"> <figure class="image is-64x64"> <img src="bird.png" alt="Image"> </figure> </div> <div class="media-content"> <div class="content"> <p> <strong>@Name</strong> <small>@SNSId</small> <br> @Content </p> </div> </div> </article> </div> @code { [Parameter] public string Name { get; set; } [Parameter] public string SNSId { get; set; } [Parameter] public string Content { get; set; } }
ここまで書いて、ようやくハッと気が付きました。
このComponent役を呼ぶと、静的ファイルのパスってどこ起点になるんでしょうか?
調べた結果、Microsoft Docs先生に答えが書いてありました。
RCL のwwwrootフォルダーに含まれるファイルは、使用中のアプリにプレフィックス content/{LIBRARY NAME}/で公開されます。 たとえば、という名前のライブラリを使用すると、 content/Razor.Class.Lib/の静的コンテンツへのパスが生成されます。
つまりMyComponent\wwwroot\bird.png
にあるファイルは_content/MyComponent/bird.png
で参照するのが正しいようです。
<img>
のsrcを_content/MyComponent/bird.png
に修正します。
以上でMyComponent側の作業は完了です。
BlaozrApp側の作成
Index.razor
にMyComponent
で作成したコンポーネントを表示します。
@page "/" <h1>Hello, world!</h1> Welcome to your new app. <MyComponent.Component1 Name="piyosi" SNSId="piyo_esq" Content="👈このかわいいトリちゃんは実家のセキセイインコです。以後よろしくお願い致します。"></MyComponent.Component1>
MyComponent
で使用しているBulma
のCSSを_Host.cshtml
でロードします。
※bootstrapとbulmaが共存している件は、サンプルコードなので無視します。
@page "/" @namespace BlazorApp.Pages @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>BlazorApp</title> <base href="~/" /> <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" /> <link href="css/site.css" rel="stylesheet" /> + <link href="_content/MyComponent/lib/bulma/css/bulma.min.css" rel="stylesheet" /> </head> <body> <app> @(await Html.RenderComponentAsync<App>(RenderMode.ServerPrerendered)) </app> <script src="_framework/blazor.server.js"></script> </body> </html>
動かしてみます
cd BlazorApp dotnet run
デフォのBootstrapも入ってるの分かりにくいですが、ちゃんとBulmaが効いています。
おわり
自分で作ったRazorClassLibraryや静的ファイルを使用するライブラリを使用する際は_content/{LibraryName}/{静的ファイルのパス}
に注意しないといけないの、覚えました。
もっと画像の表示領域を大きくしておけばよかったな、と反省しています。