Поделиться через


Расположение JavaScript в приложениях ASP.NET Core Blazor

Примечание.

Это не последняя версия этой статьи. В текущем выпуске см . версию .NET 9 этой статьи.

Предупреждение

Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в политике поддержки .NET и .NET Core. В текущем выпуске см . версию .NET 9 этой статьи.

Внимание

Эта информация относится к предварительному выпуску продукта, который может быть существенно изменен до его коммерческого выпуска. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.

В текущем выпуске см . версию .NET 9 этой статьи.

Загрузите код JavaScript (JS) одним из следующих способов:

Предупреждение

Только поместите <script> тег в файл компонента (.razor), если компонент гарантированно принимает статическую отрисовку на стороне сервера (статический SSR), так как <script> тег не может быть динамически обновлен.

Предупреждение

Не помещайте тег <script> в файл компонента (.razor), так как тег <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 необходимо анализировать в скрипте.

Загрузка скрипта в разметку элемента <body>

Поместите теги JavaScript (<script>...</script>) внутри закрывающего </body> элемента после Blazor ссылки на скрипт:

<body>
    ...

    <script src="{BLAZOR SCRIPT}"></script>
    <script>
      window.jsMethod = (methodParameter) => {
        ...
      };
    </script>
</body>

В предыдущем примере {BLAZOR SCRIPT} заполнитель — это путь к скрипту Blazor и имя файла. Сведения о расположении скрипта см. в разделе ASP.NET Структура проекта CoreBlazor.

Загрузите скрипт из внешнего файла JavaScript (.js), размещенного совместно с компонентом

Совместное размещение файлов JavaScript (JS) для Razor компонентов — удобный способ упорядочивания скриптов в приложении.

RazorКомпоненты файлов сортировки JS приложений Blazor с помощью .razor.js расширения и общедоступны адресуются с помощью пути к файлу в проекте:

{PATH}/{COMPONENT}.razor.js

  • Заполнитель {PATH} — это путь к компоненту.
  • Заполнитель {COMPONENT} — это компонент.

При публикации приложения платформа автоматически перемещает скрипт в корневой каталог. Скрипты перемещаются bin/Release/{TARGET FRAMEWORK MONIKER}/publish/wwwroot/{PATH}/{COMPONENT}.razor.jsв место, где заполнители:

  • {TARGET FRAMEWORK MONIKER} — это Moniker целевой платформы (TFM).
  • {PATH} — путь к компоненту.
  • {COMPONENT} — имя компонента.

Изменение не требуется для относительного URL-адреса скрипта, так как Blazor заботится о размещении JS файла в опубликованных статических ресурсах.

В этом разделе и приведенных ниже примерах основное внимание уделяется объяснению JS расположения файлов. В первом примере показан файл с сортировкой JS с обычной JS функцией. Второй пример демонстрирует использование модуля для загрузки функции, которая является рекомендуемой подходом для большинства рабочих приложений. Вызов JS из .NET полностью рассматривается в функциях Вызова JavaScript из методов .NET в ASP.NET Core Blazor, где существуют дополнительные объяснения BlazorJS API с дополнительными примерами. Удаление компонентов, которое представлено во втором примере, рассматривается в ASP.NET жизненном цикле основных 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 void 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 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)
            {
            }
        }
    }
}

В предыдущем примере JSDisconnectedException происходит ловушка во время удаления модуля в случае BlazorSignalR потери канала. Если предыдущий код используется в Blazor WebAssembly приложении, нет подключения к потере, SignalR поэтому можно удалить блок и оставить строку, которая удаляет try-catch модуль (await module.DisposeAsync();). Дополнительные сведения см. в разделе Взаимодействие JavaScript приложения Blazor ASP.NET Core (взаимодействие JS).

{PATH}/JsCollocation2.razor.js:

export function showPrompt2(message) {
  return prompt(message, 'Type your name here');
}

Использование скриптов и модулей для сортировки JS в Razor библиотеке классов (RCL) поддерживается только для BlazorJS механизма взаимодействия на IJSRuntime основе интерфейса. Если вы реализуете взаимодействие JavaScript, ознакомьтесь с взаимодействием JavaScript [JSImport][JSExport]/JSImport/JSExport с ASP.NET Core.Blazor

Для сценариев или модулей, предоставляемых библиотекой Razor классов (RCL) с помощью взаимодействия на IJSRuntimeоснове JS , используется следующий путь:

./_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 Структура проекта CoreBlazor.
  • Заполнитель {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 Запуск CoreBlazor.

Внедрение скрипта после запуска Blazor

Чтобы внедрить скрипт после Blazor запуска, выполните цепочку Promise с результатами вручную Blazor. Дополнительные сведения и пример см. в разделе ASP.NET Запуск CoreBlazor.

Изоляция JavaScript в модулях JavaScript

Blazorобеспечивает изоляцию JavaScript (JS) в стандартныхJS модулях (спецификация ECMAScript).

Изоляция JS обеспечивает следующие преимущества:

  • Импортированный JS не засоряет глобальное пространство имен.
  • Пользователям библиотеки и компонентов не требуется импортировать связанный код JS.

В сценариях на стороне сервера всегда ловушка JSDisconnectedException в случае потери BlazorSignalR канала предотвращает JS удаление модуля взаимодействия, что приводит к необработанным исключениям. Blazor WebAssembly приложения не используют SignalR подключение во время JS взаимодействия, поэтому нет необходимости ловушки JSDisconnectedException в Blazor WebAssembly приложениях для удаления модулей.

Дополнительные сведения см. на следующих ресурсах: