해결책은 맨 마지막에 나와있습니다.
시행착오를 겪으면서 찾아본 문서
문서에서 나온대로 따라하면 제대로 되지 않습니다. github에도 버그로 기록되어 Merge된 것으로 보아 MS공식문서이지만 신뢰할 수는 없는듯 하네요..https://github.com/dotnet/AspNetCore.Docs/issues/28044
MS권장방법1 : _Layout.cshtml에서 blazor.server.js 로딩 이후에 import
<body>
...
<script src="_framework/blazor.{webassembly|server}.js"></script>
<script src="{SCRIPT PATH AND FILE NAME (.js)}"></script>
</body>
적용 결과(실패)
@using Microsoft.AspNetCore.Components.Web
@namespace BlazorApp1.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<!DOCTYPE html>
<html dir="ltr" lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<link rel="shortcut icon" type="image/png" href="assets/images/logos/favicon.png" />
<link rel="stylesheet" href="assets/css/styles.min.css" />
<component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
</head>
<body>
@RenderBody()
<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>
<!-- Default -->
<script src="_framework/blazor.server.js"></script>
<!-- External js -->
<!-- ============================================================== -->
<script src="assets/libs/jquery/dist/jquery.min.js"></script>
<script src="assets/libs/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="assets/js/sidebarmenu.js"></script>
<script src="assets/js/app.min.js"></script>
<script src="assets/libs/apexcharts/dist/apexcharts.min.js"></script>
<script src="assets/libs/simplebar/dist/simplebar.js"></script>
<script src="assets/js/dashboard.js"></script>
</body>
</html>
MS권장방법2 : _Layout.cshtml에서 blazor.server.js 로딩할 때 autostart 속성을 false로 바꾸고, 별도의 JS함수로 Blazor Start 이후 document에 script를 로드한다.
<body>
...
<script src="_framework/blazor.{webassembly|server}.js"
autostart="false"></script>
<script>
Blazor.start().then(function () {
var customScript = document.createElement('script');
customScript.setAttribute('src', 'scripts.js');
document.head.appendChild(customScript);
});
</script>
</body>
적용결과 (아래와 같이 열심히 삽질하여 하드코딩했으나 또 실패)
@using Microsoft.AspNetCore.Components.Web
@namespace BlazorApp1.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<!DOCTYPE html>
<html dir="ltr" lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<link rel="shortcut icon" type="image/png" href="assets/images/logos/favicon.png" />
<link rel="stylesheet" href="assets/css/styles.min.css" />
<component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
</head>
<body>
@RenderBody()
<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>
<!-- Default -->
<script src="_framework/blazor.server.js" autostart="false"></script>
<!-- External js -->
<script>
Blazor.start().then(function () {
var customScript1 = document.createElement('script');
customScript1.setAttribute('src', 'assets/libs/jquery/dist/jquery.min.js'); document.head.appendChild(customScript1);
var customScript2 = document.createElement('script');
customScript2.setAttribute('src', 'assets/libs/bootstrap/dist/js/bootstrap.bundle.min.js'); document.head.appendChild(customScript2);
var customScript3 = document.createElement('script');
customScript3.setAttribute('src', 'assets/js/sidebarmenu.js'); document.head.appendChild(customScript3);
var customScript4 = document.createElement('script');
customScript4.setAttribute('src', 'assets/js/app.min.js'); document.head.appendChild(customScript4);
var customScript5 = document.createElement('script');
customScript5.setAttribute('src', 'assets/libs/apexcharts/dist/apexcharts.min.js'); document.head.appendChild(customScript5);
var customScript6 = document.createElement('script');
customScript6.setAttribute('src', 'assets/libs/simplebar/dist/simplebar.js'); document.head.appendChild(customScript6);
var customScript7 = document.createElement('script');
customScript7.setAttribute('src', 'assets/js/dashboard.js'); document.head.appendChild(customScript7);
});
</script>
*@
</body>
</html>
시행착오3) blazor.server.js가 로딩되기 이전에 호출되도록 순서를 바꾼다 ⇒ 실패
공식문서에서는 반드시 blazor.server.js를 호출한 뒤에 외부 Javascript를 불러오라고 되어있으나, 안됩니다.
github에 bug로 기록되어 1월에 고쳐진 것으로 보이며, 그 해결책으로는 호출순서를 바꾸라고 되어있으나 그렇게 해도 안됩니다.
지금부터 해결책을 설명합니다.
가장 먼저, Blazor 페이지의 상단에 IJSRuntime을 DI합니다.
@page "/test"
@inject IJSRuntime JS
그런 다음 페이지의 코드 부분에 OnAfterRenderAsync 메서드를 override하여 JSRuntime을 사용해서 Import하는 것입니다. 필요한 Javascript 파일을 각각 import하는 코드를 작성하면 됩니다.
@code {
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await JS.InvokeAsync<IJSObjectReference>("import", "./assets/libs/jquery/dist/jquery.min.js");
await JS.InvokeAsync<IJSObjectReference>("import", "./assets/libs/bootstrap/dist/js/bootstrap.bundle.min.js");
await JS.InvokeAsync<IJSObjectReference>("import", "./assets/js/sidebarmenu.js");
await JS.InvokeAsync<IJSObjectReference>("import", "./assets/js/app.min.js");
await JS.InvokeAsync<IJSObjectReference>("import", "./assets/libs/apexcharts/dist/apexcharts.min.js");
await JS.InvokeAsync<IJSObjectReference>("import", "./assets/libs/simplebar/dist/simplebar.js");
await JS.InvokeAsync<IJSObjectReference>("import", "./assets/js/dashboard.js");
}
}
}
이 방법은 Blazor에서 Javascript와 상호작용(Interaction)할 때도 마찬가지로 쓸 수 있습니다.
해결책이 나와있는 링크
https://code-maze.com/how-to-call-javascript-code-from-net-blazor-webassembly/
(해결책만 찾았다하면 마제형님꺼네요..)
