併置された JS ファイルを使用した Blazor での分離された JavaScript
以前に Blazor と JS Interop を使用したことがある場合は、さまざまなコンポーネントのランダムな関数が満載された巨大な app.js ファイルを作成したことがあるでしょう。機能しますが、すぐに面倒になってしまいます。幸いなことに、JavaScript ファイルを併置するという、よりクリーンなアプローチがあります。
アイデア
CSS 分離と同様に、Blazor では .razor.js ファイルをコンポーネントの隣に配置できます。 JavaScript モジュールは、コンポーネントが実際に必要とする場合にのみ、オンデマンドでロードされます。グローバル スクリプトや汚染はありません。
セットアップする
テキストをクリップボードにコピーする Clipboard.razor コンポーネントがあるとします。そのすぐ隣に Clipboard.razor.js という名前のファイルを作成します。
export function copyToClipboard(text) {
navigator.clipboard.writeText(text).then(() => {
console.log("Copied to clipboard!");
});
}
export キーワードに注目してください。これは重要です。 Blazor は、これを標準 ES モジュールとして読み込みます。
Blazor にモジュールをロードする
コンポーネントでは、 IJSRuntime を使用してモジュールをインポートします。パスは規則に従います。ライブラリの場合は ./_content/{ASSEMBLY_NAME}/{COMPONENT_PATH}.razor.js、または現在のプロジェクトの相対パスです。
@inject IJSRuntime JS
@implements IAsyncDisposable
<button @onclick="Copy">Copy to clipboard</button>
@code {
[Parameter]
public string Text { get; set; }
private IJSObjectReference? module;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
module = await JS.InvokeAsync<IJSObjectReference>(
"import", "./Components/Clipboard.razor.js");
}
}
private async Task Copy()
{
if (module is not null)
{
await module.InvokeVoidAsync("copyToClipboard", Text);
}
}
public async ValueTask DisposeAsync()
{
if (module is not null)
{
await module.DisposeAsync();
}
}
}
ここで注意すべき点がいくつかあります。
- サーバー側のプリレンダリング中に JS 相互運用機能が利用できないため、モジュールを
OnAfterRenderAsyncにロードします IJSObjectReferenceでモジュールへの参照を保持します。- コンポーネントが破棄されたときにモジュールをクリーンアップするために
IAsyncDisposableを実装します
なぜこれが良いのか
以前は、すべてを 1 つの wwwroot/js/app.js にダンプしていました。それは機能しましたが、関数を見つけるのは面倒で、すべてのページには必要のない JavaScript が読み込まれていました。併置された JS ファイルの場合:
- 各コンポーネントは独自の JavaScript を所有します
- モジュールは必要な場合にのみ遅延してロードされます
- グローバル関数名が競合しない
- 保守と削除が簡単 - コンポーネントを削除すると、コンポーネントと一緒に JS も削除されます。
パスに関する注意点
import に渡すパスは、スタンドアロンの Blazor アプリにいるか Razor クラス ライブラリにいるかによって異なります。通常の Blazor アプリの場合、パスは wwwroot に対する相対パスです。 .razor.js ファイルはビルド時にそこにコピーされるため、プロジェクト内のコンポーネントの場所から参照します。
モジュールのロード時に 404 が発生する場合は、パスを再確認し、ファイルが .js だけでなく .razor.js で終わることを確認してください。
投稿が気に入っていただければ幸いです!ソーシャルメディアで**@emimontesdeoca**までお気軽にご連絡ください。