확실히 8.0의 기본 Blazor 템플릿으로는 정상 작동이 되질 않네요.
슬프게도, 기본 css 조차도 먹질 않아요.
css 격리 덕분인지, Bootstrap 스타일도 먹통!
원래 기존 Blazor Server Template은,
Package 추가만 해도 버튼이 작동 하거든요.
(js import 조차 하지 않아도 가능합니다. 이전 버전 패키지에서 업그레이드 할 경우 js 배달 옵션을 끄라는 권장이 있어요.)
아무래도 Blazor App 자체의 구조가 살짝 바뀌어서 생긴 원인이 아닐까 싶은데요,
기존 Blazor Server의 경우
진입점인 Program.cs에서,
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
// 이하생략...
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
여기를 통해
_Host.cshtml → App.razor 인스턴스 활성화 → RouteView(인증이 있으면 AuthorizedRouteView가 되겠죠?) →
MainLayout.razor → [RenderFragment?]
타입인 @body
로 메인 페이지를 처음 가져오는데요.
8.0와서 기본 구조가 바뀌었더라구요.
아예 처음의 Program.cs
builder.Services.AddRazorComponents()
.AddServerComponents();
...
app.MapRazorComponents<App>()
.AddServerRenderMode();
이미 여기서부터 모양이 살짝 달라졌지요?
근데 이제 호출 따라가보면
App.razor 부터 내용이 확 달라집니다.
//- 8.0의 App.razor
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<base href="/" />
<link rel="stylesheet" href="bootstrap/bootstrap.min.css" />
<link rel="stylesheet" href="app.css" />
<link rel="stylesheet" href="BlazorApp1.styles.css" />
<link rel="icon" type="image/png" href="favicon.png" />
<HeadOutlet />
</head>
<body>
<Routes /> // <- 여길 잘 봐주세요!
<script src="_framework/blazor.web.js"></script>
</body>
</html>
///- 기존의 App.razor
<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
<NotFound>
<PageTitle>Not found</PageTitle>
<LayoutView Layout="@typeof(MainLayout)">
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
분명 다른데 익숙한 이 느낌은,
사실 8.0의 저 구조는
_Host.cshtml에 있는 내용과 매우 흡사합니다.
//_Host.cshtml
@page "/"
@using Microsoft.AspNetCore.Components.Web
@namespace BlazorApp2.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" />
<base href="~/" />
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
<link href="css/site.css" rel="stylesheet" />
<link href="BlazorApp2.styles.css" rel="stylesheet" />
<link rel="icon" type="image/png" href="favicon.png"/>
<component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
</head>
<body>
<component type="typeof(App)" render-mode="ServerPrerendered" />
<div id="blazor-error-ui">
<environment include="Staging,Production">
An error has occurred. This application may no longer respond until reloaded.
</environment>
<environment include="Development">
An unhandled exception has occurred. See browser dev tools for details.
</environment>
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
<script src="_framework/blazor.server.js"></script>
</body>
</html>
헌데 8.0 템플릿에는 Route.razor가 있지요.
막상 기존 App.razor의 내용이 여기 들어가있습니다.
//Route.razor
<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(Layout.MainLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
</Router>
심지어, MainLayout에 @body
가 있네요.
///MainLayout.razor
@inherits LayoutComponentBase
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<main>
<div class="top-row px-4">
<a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
</div>
<article class="content px-4">
@Body
</article>
</main>
</div>
<div id="blazor-error-ui">
An unhandled error has occurred.
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
그렇다면,
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
Program.cs->_Host.cshtml → App.razor 인스턴스 활성화 → RouteView(인증이 있으면 AuthorizedRouteView가 되겠죠?) →
MainLayout.razor → @body
구조에서
app.MapRazorComponents<App>()
.AddServerRenderMode();
Program.cs → App.razor → Routes.razor → MainLayout.razor → @body
로 바뀐걸로 정리 할 수 있겠습니다…만
여기서 제가 뭐가 문제인지 잘 모르겠더라고요.
여기서부터 제가 해본 시도인데,
혹시나 해서, 8.0의 Header 태그를 생성해주는 App.razor에다가
<script type="module" src="https://cdn.jsdelivr.net/npm/@fluentui/web-components/dist/web-components.min.js"></script>
을 추가했더니, 그제서야 비주얼적인 부분만 작동하더라고요. Hover 효과 등등, css부분만요!
심지어 eventHandler를 붙여도 먹통인 증상이 ㅜㅜ
혹시 ServerRender와 관련이 있는 건가?
라고 생각 했는데, 8.0부터(인 지는 모르겠습니다만…)는 prerendered가 기본값이더군요.
@attribute [RenderModeAuto(prerender:true)]