Расположение JavaScript в приложениях ASP.NET Core Blazor
Примечание.
Это не последняя версия этой статьи. Для текущего выпуска, смотрите версию .NET 9 этой статьи.
Предупреждение
Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в политике поддержки .NET и .NET Core. В текущей версии смотрите версию статьи для .NET 9.
Внимание
Эта информация относится к предварительному выпуску продукта, который может быть существенно изменен до его коммерческого выпуска. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
В текущем выпуске смотрите версию .NET 9 этой статьи.
Загрузите код JavaScript (JS) одним из следующих способов:
-
Загрузите скрипт в разметку
<head>
(как правило, не рекомендуется). -
Загрузите скрипт в разметку элемента
<body>
. -
Загрузите скрипт из внешнего файла JavaScript (
.js
), размещенного совместно с компонентом -
Загрузите скрипт из внешнего файла JavaScript (
.js
) - Внедрение скрипта до или после Blazor запуска
Встроенный JavaScript не рекомендуется использовать для Blazor приложений. Мы рекомендуем использовать JS collocation в сочетании с модулями JS.
Расположение тегов <script>
Размещайте тег <script>
в файл компонента (.razor
) только если гарантировано, что компонент будет использовать статическую серверную отрисовку без расширенной навигации. Размещение тега <script>
в файле компонента не создает предупреждение во время компиляции или ошибку, но поведение загрузки скрипта может не соответствовать вашим ожиданиям в компонентах, которые принимают интерактивный режим отрисовки или статический SSR с улучшенной навигацией.
Не помещайте тег <script>
в файл компонента (.razor
), так как тег <script>
не может изменяться динамически. Размещение тега <script>
в файле компонента приводит к ошибке во время компиляции.
Примечание.
В примерах из документации скрипты обычно размещают в теге <script>
или загружают глобальные скрипты из внешних файлов. Такие способы приводят к засорению клиента глобальными функциями. Для производственных приложений мы рекомендуем помещать JS в отдельные JS модули, которые можно импортировать при необходимости. Дополнительные сведения см. в разделе Изоляция JavaScript в модулях JavaScript.
Примечание.
В примерах из документации скрипты размещают в теге <script>
или загружают глобальные скрипты из внешних файлов. Такие способы приводят к засорению клиента глобальными функциями. Размещение JS в отдельных JS модулях, которые можно импортировать при необходимости, не поддерживается в версиях ранее Blazor, чем ASP.NET Core 5.0. Если приложению требуется использовать модули JS для изоляции JS, для сборки приложения рекомендуется использовать ASP.NET Core 5.0 или более поздней версии. Для получения дополнительных сведений в раскрывающемся списке Версия выберите статью для версии 5.0 или более поздней и ознакомьтесь с разделом Изоляция JavaScript в модулях JavaScript.
Загрузка скрипта в разметку <head>
Описанный в этом разделе подход обычно не рекомендуется использовать.
Поместите теги JavaScript (JS<script>...</script>
) в разметку <head>
элемента:
<head>
...
<script>
window.jsMethod = (methodParameter) => {
...
};
</script>
</head>
Загрузка JS из <head>
не является оптимальным способом по следующим причинам:
- Взаимодействие JS может завершиться ошибкой, если скрипт зависит от Blazor. Мы рекомендуем загружать скрипты с помощью других методов, а не через разметку
<head>
. - Страница может стать интерактивной медленнее из-за времени, необходимого для анализа JS в скрипте.
В разметке компонентов скрипты можно загружать с помощью компонента HeadContent
с обычным предупреждением о том, что подход замедляет загрузку страницы на клиенте, что рекомендуется избегать. Если скрипт загружается с компонентом HeadContent
в приложении Blazor Server, Blazor WebAssembly или Blazor Web App, используя либо интерактивный режим отрисовки (интерактивный SSR, CSR), либо статический SSR с улучшенной навигацией, переход от страницы компонента удаляет тег <script>
из отрисованного <head>
содержимого, но не выгружает код JavaScript скрипта, включая обработчики событий, которые регистрируются скриптом, и переменные и методы, предоставляемые скриптом. Только Blazor Web Appс использованием статического SSR без улучшенной навигации выгружают код JavaScript, когда пользователь покидает страницу. Как правило, вам лучше добавить теги <script>
в физическое <head>
содержимое, если вы явно хотите хранить такие ссылки на скрипты в компонентах, которые используют их, и не против, что код не выгружается при навигационных событиях.
В разметке компонентов скрипты можно загружать с помощью компонента HeadContent
с обычным предупреждением о том, что подход замедляет загрузку страницы на клиенте, что рекомендуется избегать. При загрузке скрипта с помощью компонента HeadContent
переход от страницы компонента удаляет тег <script>
из отрисованного содержимого <head>
, но не выгружает код JavaScript скрипта, включая обработчики событий, регистрируемые скриптом, а также предоставляемые скриптом переменные и методы. Как правило, вам лучше добавить теги <script>
в физическое <head>
содержимое, если вы явно хотите хранить такие ссылки на скрипты в компонентах, которые используют их, и не против, что код не выгружается при навигационных событиях.
Загрузка скрипта в разметку <body>
Поместите теги JavaScript (<script>...</script>
) внутри закрывающего </body>
элемента после Blazor ссылки на скрипт:
<body>
...
<script src="{BLAZOR SCRIPT}"></script>
<script>
window.jsMethod = (methodParameter) => {
...
};
</script>
</body>
В предыдущем примере {BLAZOR SCRIPT}
является заполнителем для пути к скрипту и имени файла Blazor. Сведения о расположении скрипта см. в разделе
Загрузите скрипт из внешнего файла JavaScript (.js
), размещенного совместно с компонентом
Совместное размещение файлов JavaScript (JS) для Razor компонентов — удобный способ упорядочивания скриптов в приложении.
Razor Компоненты приложений Blazor упорядочивают JS файлы, используя расширение .razor.js
, и могут быть общедоступны с помощью пути к файлу в проекте:
{PATH}/{COMPONENT}.razor.js
- Заполнитель
{PATH}
— это путь к компоненту. - Заполнитель
{COMPONENT}
— это компонент.
При публикации приложения платформа автоматически перемещает скрипт в корневой каталог. Скрипты перемещаются в bin/Release/{TARGET FRAMEWORK MONIKER}/publish/wwwroot/{PATH}/{COMPONENT}.razor.js
, где находятся заполнители.
-
{TARGET FRAMEWORK MONIKER}
— это монникер целевой платформы (TFM). -
{PATH}
— путь к компоненту. -
{COMPONENT}
— имя компонента.
Изменений для относительного URL-адреса скрипта не требуется, поскольку Blazor автоматически размещает файл JS в опубликованных статических ресурсах.
В этом разделе и приведенных ниже примерах основное внимание уделяется объяснению JS расположения файлов. В первом примере демонстрируется совместно расположенный JS файл с обычной JS функцией. Второй пример демонстрирует использование модуля для загрузки функции, которая является рекомендуемой подходом для большинства рабочих приложений. Вызов JS из .NET полностью раскрыт в статье Вызов функций JavaScript из методов .NET в ASP.NET Core Blazor, где представлено дальнейшее объяснение API BlazorJS с примерами. Удаление компонентов, которое представлено во втором примере, обсуждается в ASP.NET Core Razor удалении компонентов.
Следующий JsCollocation1
компонент загружает скрипт с помощью HeadContent
компонента и вызывает JS функцию с IJSRuntime.InvokeAsync. Заполнитель {PATH}
— это путь к компоненту.
Внимание
Если вы используете следующий код для демонстрации в тестовом приложении, измените {PATH}
заполнитель на путь компонента (например, Components/Pages
в .NET 8 или более поздней версии или Pages
в .NET 7 или более ранней версии). В компоненте 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 Task ShowPrompt()
{
result = await JS.InvokeAsync<string>(
"showPrompt1", "What's your name?");
StateHasChanged();
}
}
Совместно расположенный файл JS помещается рядом с файлом компонента JsCollocation1
с именем JsCollocation1.razor.js
. В компоненте JsCollocation1
скрипт ссылается на путь к сопутствующему файлу. В следующем примере showPrompt1
функция принимает имя пользователя из объекта Window prompt()
и возвращает его компоненту JsCollocation1
для отображения.
{PATH}/JsCollocation1.razor.js
:
function showPrompt1(message) {
return prompt(message, 'Type your name here');
}
Предыдущий подход не рекомендуется использовать в рабочих приложениях, так как подход загрязняет клиента глобальными функциями. Лучший подход для рабочих приложений — использовать JS модули. Те же общие принципы применяются к загрузке JS модуля из коллакуированного JS файла, как показано в следующем примере.
Метод следующего JsCollocation2
компонента OnAfterRenderAsync
загружает модуль JS в module
, который является IJSObjectReference класса компонента.
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 Task 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)
{
}
}
}
}
В предыдущем примере JSDisconnectedException остаётся в процессе удаления модуля, если контур BlazorSignalR потерян. Если предыдущий код используется в Blazor WebAssembly приложении, нет подключения, которое можно потерять, SignalR поэтому можно удалить блок и оставить строку, которая освобождает try
-catch
модуль (await module.DisposeAsync();
). Дополнительные сведения см. в разделе Интероперабельность JavaScript в ASP.NET Core Blazor (JS interop).
{PATH}/JsCollocation2.razor.js
:
export function showPrompt2(message) {
return prompt(message, 'Type your name here');
}
Внимание
Не размещайте тег <script>
для JsCollocation2.razor.js
после скрипта Blazor, так как модуль загружается и кэшируется автоматически при вызове динамического import()
.
Использование скриптов и модулей для сортировки JS в Razor библиотеке классов (RCL) поддерживается только для BlazorJS механизма взаимодействия на IJSRuntime основе интерфейса. Если вы реализуете взаимодействие с JavaScript, ознакомьтесь с
Для сценариев или модулей, предоставляемых библиотекой Razor классов (RCL) с помощью взаимодействия на основе IJSRuntimeJS, используется следующий путь:
./_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
находится в папкеComponents/Pages
библиотеки RCL.
module = await JS.InvokeAsync<IJSObjectReference>("import",
"./_content/AppJS/Components/Pages/JsCollocation3.razor.js");
Дополнительные сведения о RCL см. в статье Использование компонентов Razor в ASP.NET Core из библиотеки классов Razor (RCL).
Загрузите скрипт из внешнего файла JavaScript (.js
)
Поместите теги JavaScript (JS) с источником скрипта (<script>...</script>
src
) путь внутри закрывающего </body>
элемента после Blazor ссылки на скрипт:
<body>
...
<script src="{BLAZOR SCRIPT}"></script>
<script src="{SCRIPT PATH AND FILE NAME (.js)}"></script>
</body>
Для заполнителей в предыдущем примере:
- Заполнитель
{BLAZOR SCRIPT}
— это путь к скрипту Blazor и имя файла. Сведения о расположении скрипта см. в разделеструктура проекта ASP.NET Core . - Заполнитель
{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>
Если внешний файл JS предоставляется библиотекой классов Razor, укажите файл JS, используя его стабильный путь к статическому веб-активу _content/{PACKAGE ID}/{SCRIPT PATH AND FILE NAME (.js)}
.
- Заполнитель
{PACKAGE ID}
— это идентификатор пакета библиотеки. Идентификатор пакета по умолчанию имеет имя сборки проекта, если значение<PackageId>
не указано в файле проекта. - Заполнитель
{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>
Дополнительные сведения см. в статье Использование компонентов Razor в ASP.NET Core из библиотеки классов Razor (RCL).
Внедрить скрипт до или после запуска Blazor.
Чтобы обеспечить загрузку скриптов до или после Blazor запуска, используйте инициализатор JavaScript. Дополнительные сведения и примеры см. в разделе ASP.NET Core Blazor стартап.
Внедрение скрипта после запуска Blazor
Чтобы внедрить скрипт после запуска Blazor, свяжитесь с Promise
, который возникает из-за ручного запуска Blazor. Дополнительные сведения и пример см. в разделе ASP.NET CoreBlazor startup.
Изоляция JavaScript в модулях JavaScript
Blazorобеспечивает изоляцию JavaScript (JS) в стандартныхJSмодулях (спецификация ECMAScript).
Изоляция JS обеспечивает следующие преимущества:
- Импортированный JS не засоряет глобальное пространство имен.
- Пользователям библиотеки и компонентов не требуется импортировать связанный код JS.
В серверных сценариях всегда обрабатывайте JSDisconnectedException, в случае если потеря цепи BlazorSignalR предотвращает вызов взаимодействия JS от освобождения модуля, что приводит к необработанному исключению. Blazor WebAssembly приложения не используют SignalR подключение во время JS взаимодействия, поэтому нет необходимости отлавливать JSDisconnectedException в Blazor WebAssembly приложениях для освобождения модулей.
Дополнительные сведения см. на следующих ресурсах:
ASP.NET Core