Ubicación de JavaScript en aplicaciones Blazor de ASP.NET Core

Nota:

Esta no es la versión más reciente de este artículo. Para la versión actual, consulte la versión .NET 8 de este artículo.

Importante

Esta información hace referencia a un producto en versión preliminar, el cual puede sufrir importantes modificaciones antes de que se publique la versión comercial. Microsoft no proporciona ninguna garantía, expresa o implícita, con respecto a la información proporcionada aquí.

Para la versión actual, consulte la versión .NET 8 de este artículo.

Cargue el código de JavaScript (JS) mediante cualquiera de los enfoques siguientes:

Advertencia

Coloque solo una etiqueta <script> en un archivo de componente (.razor) si se garantiza que el componente adoptará la representación estática del lado servidor (SSR estática) porque la etiqueta <script> no se puede actualizar de forma dinámica.

Advertencia

No coloque una etiqueta <script> en un archivo de componente (.razor), porque la etiqueta <script> no se puede actualizar dinámicamente.

Nota:

En los ejemplos de la documentación se suelen colocar los scripts en una etiqueta <script> o se cargan scripts globales desde archivos externos. Estos enfoques contaminan el cliente con funciones globales. En el caso de las aplicaciones de producción, se recomienda colocar JS en módulos de JS independiente que se puedan importar cuando sea necesario. Para más información, consulte la sección Aislamiento de JavaScript en módulos de JavaScript.

Nota:

En los ejemplos de la documentación se colocan los scripts en una etiqueta <script> o se cargan scripts globales desde archivos externos. Estos enfoques contaminan el cliente con funciones globales. La colocación de JS en módulos de JS independientes que se puedan importar cuando sea necesario no se admite en versiones de Blazor anteriores a ASP.NET Core 5.0. Si la aplicación requiere el uso de módulos de JS para el aislamiento de JS, se recomienda usar ASP.NET Core 5.0 o posterior para compilar la aplicación. Para más información, use la lista desplegable Versión para seleccionar una versión 5.0 o posterior de este artículo y consulte la sección Aislamiento de JavaScript en módulos de JavaScript.

Cargar un script en el marcado <head>

Por lo general, no se recomienda el enfoque de esta sección.

Coloque las etiquetas (JS) de JavaScript (<script>...</script>) en el <head> marcado del elemento:

<head>
    ...

    <script>
      window.jsMethod = (methodParameter) => {
        ...
      };
    </script>
</head>

Cargar JS desde <head> no es el mejor enfoque por las razones siguientes:

  • La interoperabilidad de JS puede producir un error si el script depende de Blazor. Se recomienda cargar los scripts mediante uno de los otros enfoques, no a través del marcado <head>.
  • La página puede volverse interactiva más lentamente debido al tiempo que se tarda en analizar JS en el script.

Cargar un script en el marcado <body>

Coloque las etiquetas de JavaScript (<script>...</script>) dentro del elemento </body> de cierre después de la referencia al script Blazor:

<body>
    ...

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

En el ejemplo anterior, el marcador de posición {BLAZOR SCRIPT} es la ruta de acceso del script y el nombre de archivo Blazor. Para obtener la ubicación del script, consulte la estructura del proyecto ASP.NET CoreBlazor.

Carga de un script desde un archivo JavaScript externo (.js) colocado con un componente

La colocación de archivos de JavaScript (JS) para componentes Razor es una manera cómoda de organizar los scripts en una aplicación.

Los componentes Razor de aplicaciones Blazor intercalan archivos JS mediante la extensión .razor.js y se pueden direccionar públicamente mediante la ruta de acceso al archivo del proyecto:

{PATH}/{COMPONENT}.razor.js

  • El marcador de posición {PATH} es la ruta de acceso al componente.
  • El marcador de posición {COMPONENT} es el componente.

Cuando se publica la aplicación, el marco mueve automáticamente el script a la raíz web. Los scripts se mueven a bin/Release/{TARGET FRAMEWORK MONIKER}/publish/wwwroot/{PATH}/{COMPONENT}.razor.js, donde los marcadores de posición son:

No se requiere ningún cambio en la dirección URL relativa del script, ya que Blazor se encarga de colocar el archivo JS en los recursos estáticos publicados por usted.

Esta sección y los ejemplos siguientes se centran principalmente en explicar la intercalación de archivos JS. En el primer ejemplo se muestra un archivo intercalado JS con una función normal JS. En el segundo ejemplo se muestra el uso de un módulo para cargar una función, que es el enfoque recomendado para la mayoría de las aplicaciones de producción. Las llamadas JS desde .NET se tratan completamente en Llamar a funciones de JavaScript desde métodos de .NET en ASP.NET Core Blazor, donde hay más explicaciones de la BlazorJS API con ejemplos adicionales. La eliminación de componentes, que está presente en el segundo ejemplo, se trata en ASP.NET Core Razor ciclo de vida de componentes.

El siguiente JsCollocation1 componente carga un script a través de un HeadContent componente y llama a una JS función con IJSRuntime.InvokeAsync. El marcador de posición {PATH} es la ruta de acceso al componente.

Importante

Si usa el código siguiente para una demostración en una aplicación de prueba, cambie el {PATH} marcador de posición a la ruta de acceso del componente (ejemplo: Components/Pages en .NET 8 o posterior o Pages en .NET 7 o anterior). En una aplicación web Blazor (.NET 8 o posterior), el componente requiere un modo de representación interactivo aplicado globalmente a la aplicación o a la definición del componente.

Agregue el siguiente script después del script Blazor (ubicación del Blazor script de inicio ):

<script src="{PATH}/JsCollocation1.razor.js"></script>

Componente 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();
    }
}

El archivo colocado JS se coloca junto al archivo de JsCollocation1 componente con el nombre de archivoJsCollocation1.razor.js. En el componente JsCollocation1, se hace referencia al script en la ruta de acceso del archivo intercalado. En el ejemplo siguiente, la función showPrompt1 acepta el nombre del usuario de un Window prompt() y lo devuelve al componente JsCollocation1 para mostrarlo.

{PATH}/JsCollocation1.razor.js:

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

El enfoque anterior no se recomienda para su uso general en aplicaciones de producción porque contamina el cliente con funciones globales. Un mejor enfoque para las aplicaciones de producción es usar módulos JS. Los mismos principios generales se aplican a la carga JS de un módulo desde un archivo combinado JS, como se muestra en el siguiente ejemplo.

El método del siguiente componente JsCollocation2OnAfterRenderAsync carga un módulo JS en module, que es una IJSObjectReference de la clase de componente. module se usa para llamar a la función showPrompt2. El marcador de posición {PATH} es la ruta de acceso al componente.

Importante

Si usa el código siguiente para una demostración en una aplicación de prueba, cambie el {PATH} marcador de posición a la ruta de acceso del componente. En una aplicación web Blazor (.NET 8 o posterior), el componente requiere un modo de representación interactivo aplicado globalmente a la aplicación o a la definición del componente.

Componente 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)
        {
            await module.DisposeAsync();
        }
    }
}

{PATH}/JsCollocation2.razor.js:

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

En el caso de los scripts o módulos proporcionados por una biblioteca de clases (RCL) Razor, se usa la siguiente ruta de acceso:

_content/{PACKAGE ID}/{PATH}/{COMPONENT}.{EXTENSION}.js

  • El marcador de posición {PACKAGE ID} es el identificador de paquete de la RCL (o el nombre de la biblioteca para una biblioteca de clases a la que hace referencia la aplicación).
  • El marcador de posición {PATH} es la ruta de acceso al componente. Si un componente Razor se encuentra en la raíz de la RCL, no se incluye el segmento de ruta.
  • El marcador de posición {COMPONENT} es el componente.
  • El marcador de posición {EXTENSION} coincide con la extensión de la componente, ya sea razor o cshtml.

En el ejemplo siguiente de aplicación Blazor:

  • El identificador de paquete de la RCL es AppJS.
  • Los scripts de un módulo se cargan para el componente JsCollocation3 (JsCollocation3.razor).
  • El componente JsCollocation3 está en la carpeta Components/Pages de la RCL.
module = await JS.InvokeAsync<IJSObjectReference>("import", 
    "./_content/AppJS/Components/Pages/JsCollocation3.razor.js");

Para más información sobre las RCL, consulte Consumo de componentes Razor de ASP.NET Core a partir de una biblioteca de clases de Razor (RCL).

Carga de un script desde un archivo JavaScript externo (.js)

Coloque las etiquetas (JS) JavaScript (<script>...</script>) con una ruta de origen de script (src) dentro </body> del elemento de cierre después de la referencia de script Blazor:

<body>
    ...

    <script src="{BLAZOR SCRIPT}"></script>
    <script src="{SCRIPT PATH AND FILE NAME (.js)}"></script>
</body>

En el ejemplo anterior:

  • El marcador de posición {BLAZOR SCRIPT} es la ruta de acceso del script y el nombre de archivo de Blazor. Para obtener la ubicación del script, consulte la estructura del proyecto ASP.NET CoreBlazor.
  • El marcador de posición {SCRIPT PATH AND FILE NAME (.js)} es la ruta de acceso y el nombre del archivo de script en wwwroot.

En el ejemplo siguiente de la etiqueta <script> anterior, el archivo scripts.js se encuentra en la carpeta wwwroot/js de la aplicación:

<script src="js/scripts.js"></script>

También puede servir scripts directamente desde la carpeta wwwroot si prefiere no guardar todos sus scripts en una carpeta separada bajo wwwroot:

<script src="scripts.js"></script>

Cuando una biblioteca de clases de Razor proporcione el archivo externo JS, especifique el archivo JS mediante su ruta de acceso estática estable del recurso web: ./_content/{PACKAGE ID}/{SCRIPT PATH AND FILE NAME (.js)}:

  • El segmento de trazado del directorio actual (./) es necesario para crear la ruta de recurso estático correcta para el archivo JS.
  • El marcador de posición {PACKAGE ID} es el id. de paquete de la biblioteca. El id. de paquete tiene como valor predeterminado el nombre de ensamblado del proyecto si <PackageId> no se especifica en el archivo del proyecto.
  • El marcador de posición {SCRIPT PATH AND FILE NAME (.js)} es la ruta de acceso y el nombre de archivo en wwwroot.
<body>
    ...

    <script src="{BLAZOR SCRIPT}"></script>
    <script src="./_content/{PACKAGE ID}/{SCRIPT PATH AND FILE NAME (.js)}"></script>
</body>

En el ejemplo siguiente de la etiqueta <script> anterior:

  • La biblioteca de clases Razor tiene un nombre de ensamblado de ComponentLibrary, y un <PackageId> no se especifica en el archivo del proyecto de la biblioteca.
  • El archivo scripts.js está en la carpeta wwwroot de la biblioteca de clases.
<script src="./_content/ComponentLibrary/scripts.js"></script>

Para obtener más información, vea Consumo de componentes Razor de ASP.NET Core a partir de una biblioteca de clases de Razor (RCL).

Insertar un script antes o después Blazor del inicio

Para asegurarse de que los scripts se cargan antes o después de iniciarse Blazor, utilice un inicializador de JavaScript. Para obtener más información y ejemplos, consulte Inicio de ASP.NET Core Blazor.

Insertar un script después de que se inicia Blazor

Para insertar un script después de iniciarBlazor, encadene al Promise que resulta de un arranque manual de Blazor. Para obtener más información y un ejemplo, consulte Guía de Blazor para ASP.NET Core.

Aislamiento de JavaScript en módulos de JavaScript

Blazor permite el aislamiento de JavaScript (JS) en módulos de JS estándar (especificación de ECMAScript).

El aislamiento de JS proporciona las siguientes ventajas:

  • El JS importado no contamina el espacio de nombres global.
  • No es necesario que los consumidores de una biblioteca y los componentes importen el código de JS relacionado.

Para más información, vea Llamada a funciones de JavaScript desde métodos de .NET en Blazor de ASP.NET Core.

La importación dinámica con el operador import() se admite con ASP.NET Core y Blazor:

if ({CONDITION}) import("/additionalModule.js");

En el ejemplo anterior, el marcador de posición {CONDITION} representa una comprobación condicional para determinar si se debe cargar el módulo.

Para la compatibilidad del explorador, consulte ¿Puedo utilizar: Módulos JavaScript: importación dinámica?