ASP.NET Core Blazor アプリでの JavaScript の場所
Note
これは、この記事の最新バージョンではありません。 現在のリリースについては、この記事の .NET 9 バージョンを参照してください。
警告
このバージョンの ASP.NET Core はサポート対象から除外されました。 詳細については、 .NET および .NET Core サポート ポリシーを参照してください。 現在のリリースについては、この記事の .NET 9 バージョンを参照してください。
重要
この情報はリリース前の製品に関する事項であり、正式版がリリースされるまでに大幅に変更される可能性があります。 Microsoft はここに示されている情報について、明示か黙示かを問わず、一切保証しません。
現在のリリースについては、この記事の .NET 9 バージョンを参照してください。
JavaScript (JS) のコードを読み込むには、次のいずれかの方法を使用します。
警告
<script>
タグは動的に更新できないため、コンポーネントが静的サーバー側レンダリング (静的 SSR) を採用することが保証されている場合にのみ、コンポーネント ファイル (.razor
) に <script>
タグを配置します。
警告
<script>
タグは動的に更新できないため、<script>
タグをコンポーネント ファイル (.razor
) 内に配置しないでください。
Note
ドキュメントの例では、通常、スクリプトを <script>
タグに配置するか、または外部ファイルからグローバル スクリプトを読み込みます。 これらの方法では、グローバル関数でクライアントが汚染されます。 運用アプリの場合は、必要に応じてインポートできる別の JS モジュールに JS を配置することをお勧めします。 詳細については、「JavaScript モジュールでの JavaScript の分離」セクションを参照してください。
Note
ドキュメントの例では、<script>
タグにスクリプトを配置するか、または外部ファイルからグローバル スクリプトを読み込みます。 これらの方法では、グローバル関数でクライアントが汚染されます。 必要に応じてインポートできる別の JS モジュールへの JS の配置は、ASP.NET Core 5.0 より前の Blazor ではサポートされていません。 アプリで JS の分離のために JS モジュールを使用する必要がある場合は、ASP.NET Core 5.0 以降を使用してアプリをビルドすることをお勧めします。 詳細については、[バージョン] ドロップダウン リストを使用して、この記事の 5.0 以降のバージョンを選択し、「JavaScript モジュールでの JavaScript の分離」セクションを参照してください。
<head>
マークアップでスクリプトを読み込む
このセクションのアプローチは、一般的には推奨されていません。
JavaScript (JS) タグ (<script>...</script>
) を<head>
要素マークアップに配置します。
<head>
...
<script>
window.jsMethod = (methodParameter) => {
...
};
</script>
</head>
<head>
から JS を読み込むことは、次の理由により最適な方法ではありません。
- スクリプトが Blazor に依存している場合、JS 相互運用が失敗するおそれがあります。
<head>
マークアップではなく、他の方法のいずれかを使用してスクリプトを読み込むことをお勧めします。 - スクリプト内で JS を解析するのに時間がかかるため、ページの動作が遅くなることがあります。
<body>
マークアップでスクリプトを読み込む
Blazor スクリプト参照の後の終了 </body>
要素内に JavaScript タグ (<script>...</script>
) を配置します。
<body>
...
<script src="{BLAZOR SCRIPT}"></script>
<script>
window.jsMethod = (methodParameter) => {
...
};
</script>
</body>
前の例の {BLAZOR SCRIPT}
プレースホルダーは、Blazor スクリプトのパスとファイル名です。 スクリプトの場所については、「ASP.NET Core Blazor プロジェクトの構造」を参照してください。
コンポーネントと同じ場所に存在する外部 JavaScript ファイル (.js
) からスクリプトを読み込む
Razor コンポーネントの JavaScript (JS) ファイルの併置は、アプリでスクリプトを整理する便利な方法です。
Blazor アプリの Razor コンポーネントは、.razor.js
拡張子を使って JS ファイルを併置し、プロジェクト内のファイルへのパスを使ってパブリックにアドレス指定できます。
{PATH}/{COMPONENT}.razor.js
{PATH}
プレースホルダーは、コンポーネントへのパスです。{COMPONENT}
プレースホルダーはコンポーネントです。
アプリが公開されると、スクリプトはフレームワークによって Web ルートに自動的に移動されます。 スクリプトは、bin/Release/{TARGET FRAMEWORK MONIKER}/publish/wwwroot/{PATH}/{COMPONENT}.razor.js
に移動されます。プレースホルダーの内容は次のとおりです。
{TARGET FRAMEWORK MONIKER}
は、ターゲット フレームワーク モニカー (TFM) です。{PATH}
は、コンポーネントへのパスです。{COMPONENT}
はコンポーネント名です。
公開される静的資産への JS ファイルの配置は Blazor によって自動的に処理されるので、スクリプトの相対 URL を変更する必要はありません。
このセクションと以下の例では、主に JS ファイルの併置について説明することに重点を置きます。 最初に、通常の JS 関数で併置される JS ファイルの例を示します。 次に、モジュールを使って関数を読み込む例を示します。これは、ほとんどの運用アプリに推奨されるアプローチです。 .NET からの JS の呼び出しについては「ASP.NET Core Blazor で .NET メソッドから JavaScript 関数を呼び出す」で詳細に説明されており、そこに BlazorJS API のさらに詳しい説明と他の例があります。 2 番目の例で示されているコンポーネントの破棄については、「ASP.NET Core Razor コンポーネントのライフサイクル」で説明されています。
次の JsCollocation1
コンポーネントでは、HeadContent
コンポーネントを介してスクリプトを読み込み、IJSRuntime.InvokeAsync を使って JS 関数を呼び出しています。 {PATH}
プレースホルダーは、コンポーネントへのパスです。
重要
テスト アプリで実際に次のコードを使ってみる場合は、{PATH}
プレースホルダーをコンポーネントのパスに変更してください (例: .NET 8 以降の場合は Components/Pages
、.NET 7 以前の場合は Pages
)。 Blazor Web App (.NET 8 以降) のコンポーネントでは、対話型レンダリング モードを、アプリにグローバルに適用するか、コンポーネント定義に適用する必要があります。
Blazor スクリプト (Blazor 開始スクリプトの場所) の後に次のスクリプトを追加します。
<script src="{PATH}/JsCollocation1.razor.js"></script>
JsCollocation1
コンポーネント ({PATH}/JsCollocation1.razor
):
@page "/js-collocation-1"
@inject IJSRuntime JS
<PageTitle>JS Collocation 1</PageTitle>
<h1>JS Collocation Example 1</h1>
<button @onclick="ShowPrompt">Call showPrompt1</button>
@if (!string.IsNullOrEmpty(result))
{
<p>
Hello @result!
</p>
}
@code {
private string? result;
public async void ShowPrompt()
{
result = await JS.InvokeAsync<string>(
"showPrompt1", "What's your name?");
StateHasChanged();
}
}
併置される JS ファイルは、JsCollocation1.razor.js
というファイル名で JsCollocation1
コンポーネント ファイルに隣接して配置されます。 JsCollocation1
コンポーネント内では、スクリプトは併置されたファイルのパスで参照されます。 次の例の showPrompt1
関数は、Window prompt()
からユーザーの名前を受け取り、それを表示するために JsCollocation1
コンポーネントに返します。
{PATH}/JsCollocation1.razor.js
:
function showPrompt1(message) {
return prompt(message, 'Type your name here');
}
上記の方法は、グローバル関数でクライアントを汚染するため、運用アプリでの一般的な使用には推奨されません。 運用アプリのためのさらに優れたアプローチは、JS モジュールを使うことです。 次の例で示すように、併置された JS ファイルからの JS モジュールの読み込みにも同じ一般的な原則が適用されます。
次の JsCollocation2
コンポーネントの OnAfterRenderAsync
メソッドは、コンポーネント クラスの IJSObjectReference である module
に JS モジュールを読み込みます。 module
は、showPrompt2
関数を呼び出すために使われます。 {PATH}
プレースホルダーは、コンポーネントへのパスです。
重要
テスト アプリで実際に次のコードを使ってみる場合は、{PATH}
プレースホルダーをコンポーネントのパスに変更してください。 Blazor Web App (.NET 8 以降) のコンポーネントでは、対話型レンダリング モードを、アプリにグローバルに適用するか、コンポーネント定義に適用する必要があります。
JsCollocation2
コンポーネント ({PATH}/JsCollocation2.razor
):
@page "/js-collocation-2"
@implements IAsyncDisposable
@inject IJSRuntime JS
<PageTitle>JS Collocation 2</PageTitle>
<h1>JS Collocation Example 2</h1>
<button @onclick="ShowPrompt">Call showPrompt2</button>
@if (!string.IsNullOrEmpty(result))
{
<p>
Hello @result!
</p>
}
@code {
private IJSObjectReference? module;
private string? result;
protected async override Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
/*
Change the {PATH} placeholder in the next line to the path of
the collocated JS file in the app. Examples:
./Components/Pages/JsCollocation2.razor.js (.NET 8 or later)
./Pages/JsCollocation2.razor.js (.NET 7 or earlier)
*/
module = await JS.InvokeAsync<IJSObjectReference>("import",
"./{PATH}/JsCollocation2.razor.js");
}
}
public async void ShowPrompt()
{
if (module is not null)
{
result = await module.InvokeAsync<string>(
"showPrompt2", "What's your name?");
StateHasChanged();
}
}
async ValueTask IAsyncDisposable.DisposeAsync()
{
if (module is not null)
{
try
{
await module.DisposeAsync();
}
catch (JSDisconnectedException)
{
}
}
}
}
前の例では、BlazorのSignalR回路が失われた場合に、モジュールの破棄中にJSDisconnectedExceptionがトラップされます。 上記のコードが Blazor WebAssembly アプリで使用されている場合、失われる SignalR 接続がないため、 try
-catch
ブロックを削除し、モジュールを破棄する行 (await module.DisposeAsync();
) のままにすることができます。 詳しくは、「ASP.NET Core Blazor JavaScript の相互運用性 (JS 相互運用)」をご覧ください。
{PATH}/JsCollocation2.razor.js
:
export function showPrompt2(message) {
return prompt(message, 'Type your name here');
}
Razor クラス ライブラリ (RCL) での併置された JS に対するスクリプトとモジュールの使用は、IJSRuntime インターフェイスに基づく Blazor の JS 相互運用メカニズムでのみサポートされます。 JavaScript [JSImport]
/[JSExport]
相互運用を実装する場合は、「ASP.NET Core Blazor を使用した JavaScript JSImport/JSExport の相互運用」をご覧ください。
IJSRuntime ベースの JS 相互運用を使用して Razor クラス ライブラリ (RCL) によって提供されるスクリプトまたはモジュールの場合は、次のパスが使われます。
./_content/{PACKAGE ID}/{PATH}/{COMPONENT}.{EXTENSION}.js
- JS ファイルへの正しい静的アセット パスを作成するためには、現在のディレクトリ (
./
) に対するパス セグメントが必要です。 {PACKAGE ID}
プレースホルダーは、RCL のパッケージ識別子 (または、アプリによって参照されるクラス ライブラリのライブラリ名) です。{PATH}
プレースホルダーは、コンポーネントへのパスです。 Razor コンポーネントが RCL のルートにある場合、パス セグメントは含まれません。{COMPONENT}
プレースホルダーはコンポーネント名です。{EXTENSION}
プレースホルダーは、コンポーネントの拡張子 (razor
またはcshtml
) と一致します。
次の Blazor アプリの例の場合:
- RCL のパッケージ識別子は
AppJS
です。 - モジュールのスクリプトは、
JsCollocation3
コンポーネント (JsCollocation3.razor
) に対して読み込まれます。 JsCollocation3
コンポーネントは、RCL のComponents/Pages
フォルダーにあります。
module = await JS.InvokeAsync<IJSObjectReference>("import",
"./_content/AppJS/Components/Pages/JsCollocation3.razor.js");
RCL の詳細については、「ASP.NET Core Razor コンポーネントを Razor クラス ライブラリから使用する」を参照してください。
外部 JavaScript ファイル (.js
) からスクリプトを読み込む
Blazor スクリプト参照の後の終了</body>
要素内に、スクリプト ソース (src
) パスを使用して JavaScript (JS) のタグ (<script>...</script>
) を配置します。
<body>
...
<script src="{BLAZOR SCRIPT}"></script>
<script src="{SCRIPT PATH AND FILE NAME (.js)}"></script>
</body>
前の例のプレースホルダーの場合:
{BLAZOR SCRIPT}
プレースホルダーは、Blazor スクリプトのパスとファイル名です。 スクリプトの場所については、「ASP.NET Core Blazor プロジェクトの構造」を参照してください。{SCRIPT PATH AND FILE NAME (.js)}
プレースホルダーは、wwwroot
の下のパスとスクリプト ファイル名です。
上記の <script>
タグの次の例では、scripts.js
ファイルはアプリの wwwroot/js
フォルダーにあります。
<script src="js/scripts.js"></script>
すべてのスクリプトを wwwroot
の下の別のフォルダーに保存したくない場合は、wwwroot
フォルダーから直接スクリプトを提供することもできます。
<script src="scripts.js"></script>
Razor クラス ライブラリによって外部の JS ファイルが提供される場合は、安定した静的 Web アセット パス _content/{PACKAGE ID}/{SCRIPT PATH AND FILE NAME (.js)}
を使用して JS ファイルを指定します。
{PACKAGE ID}
プレースホルダーは、ライブラリのパッケージ ID です。 プロジェクト ファイルで<PackageId>
が指定されていない場合、パッケージ ID の既定値はプロジェクトのアセンブリ名になります。{SCRIPT PATH AND FILE NAME (.js)}
プレースホルダーは、wwwroot
の下のパスとファイル名です。
<body>
...
<script src="{BLAZOR SCRIPT}"></script>
<script src="_content/{PACKAGE ID}/{SCRIPT PATH AND FILE NAME (.js)}"></script>
</body>
上記の <script>
タグの例を次に示します。
- Razor クラス ライブラリのアセンブリ名は
ComponentLibrary
であり、<PackageId>
はライブラリのプロジェクト ファイルで指定されません。 scripts.js
ファイルは、クラス ライブラリのwwwroot
フォルダーにあります。
<script src="_content/ComponentLibrary/scripts.js"></script>
詳細については、「ASP.NET Core Razor コンポーネントを Razor クラス ライブラリから使用する」を参照してください。
Blazor の開始前または開始後にスクリプトを挿入する
Blazor の開始前または開始後にスクリプトが確実に読み込まれるようにするには、JavaScript 初期化子を使用します。 詳細と例については、「ASP.NET Core のBlazor起動」を参照してください。
Blazor の開始後にスクリプトを挿入する
Blazor の開始後にスクリプトを挿入するには、Blazor を手動で開始した結果の Promise
にチェーンします。 詳細と例については、「ASP.NET Core のBlazor起動」を参照してください。
JavaScript モジュールでの JavaScript の分離
Blazor では、標準の JS モジュールに JavaScript (JS) を分離できます (ECMAScript の仕様)。
JS を分離すると、次のようなベネフィットがあります。
- インポートされる JS によって、グローバル名前空間が汚染されなくなります。
- ライブラリおよびコンポーネントのコンシューマーは、関連する JS をインポートする必要がありません。
サーバー側のシナリオでは、BlazorのSignalR回線が失われると、JS相互運用呼び出しによってモジュールが破棄されるのを防ぎ、ハンドルされない例外が発生した場合に、常にJSDisconnectedExceptionをトラップします。 Blazor WebAssemblyアプリは、JS相互運用中にSignalR接続を使用しないため、モジュールを破棄するためにBlazor WebAssemblyアプリでJSDisconnectedExceptionをトラップする必要はありません。
詳細については、次のリソースを参照してください。
ASP.NET Core