From a7318ef8609c3c9615b15961d84fde150d7e508f Mon Sep 17 00:00:00 2001
From: guardrex <1622880+guardrex@users.noreply.github.com>
Date: Fri, 24 Feb 2023 12:48:29 -0600
Subject: [PATCH 1/9] Additional JS initializer scenarios
---
aspnetcore/blazor/fundamentals/startup.md | 100 +++++++++++++++++-
.../javascript-interoperability/index.md | 6 ++
2 files changed, 103 insertions(+), 3 deletions(-)
diff --git a/aspnetcore/blazor/fundamentals/startup.md b/aspnetcore/blazor/fundamentals/startup.md
index 46e052c103d9..6fec6b1a5bd4 100644
--- a/aspnetcore/blazor/fundamentals/startup.md
+++ b/aspnetcore/blazor/fundamentals/startup.md
@@ -36,8 +36,8 @@ To define a JS initializer, add a JS module to the project named `{NAME}.lib.mod
The module exports either or both of the following conventional functions:
* `beforeStart(options, extensions)`: Called before Blazor starts. For example, `beforeStart` is used to customize the loading process, logging level, and other options specific to the hosting model.
- * In Blazor WebAssembly, `beforeStart` receives the Blazor WebAssembly options (`options` in this section's example) and any extensions (`extensions` in this section's example) added during publishing. For example, options can specify the use of a custom [boot resource loader](xref:blazor/fundamentals/startup#load-boot-resources).
- * In Blazor Server, `beforeStart` receives SignalR circuit start options (`options` in this section's example).
+ * In Blazor WebAssembly, `beforeStart` receives the Blazor WebAssembly options (`options` in this section's examples) and any extensions (`extensions` in this section's examples) added during publishing. For example, options can specify the use of a custom [boot resource loader](xref:blazor/fundamentals/startup#load-boot-resources).
+ * In Blazor Server, `beforeStart` receives SignalR circuit start options (`options` in this section's examples).
* In [`BlazorWebViews`](/mobile-blazor-bindings/walkthroughs/hybrid-hello-world#mainrazor-native-ui-page), no options are passed.
* `afterStarted`: Called after Blazor is ready to receive calls from JS. For example, `afterStarted` is used to initialize libraries by making JS interop calls and registering custom elements. The Blazor instance is passed to `afterStarted` as an argument (`blazor` in this section's example).
@@ -46,7 +46,7 @@ For the filename:
* If the JS initializers are consumed as a static asset in the project, use the format `{ASSEMBLY NAME}.lib.module.js`, where the `{ASSEMBLY NAME}` placeholder is the app's assembly name. For example, name the file `BlazorSample.lib.module.js` for a project with an assembly name of `BlazorSample`. Place the file in the app's `wwwroot` folder.
* If the JS initializers are consumed from an RCL, use the format `{LIBRARY NAME/PACKAGE ID}.lib.module.js`, where the `{LIBRARY NAME/PACKAGE ID}` placeholder is the project's library name or package identifier. For example, name the file `RazorClassLibrary1.lib.module.js` for an RCL with a package identifier of `RazorClassLibrary1`. Place the file in the library's `wwwroot` folder.
-The following example demonstrates JS initializers that load custom scripts before and after Blazor has started:
+The following example demonstrates JS initializers that load custom scripts before and after Blazor has started by appending them to the `
` in `beforeStart` and `afterStarted`:
```javascript
export function beforeStart(options, extensions) {
@@ -62,6 +62,8 @@ export function afterStarted(blazor) {
}
```
+The preceding `beforeStart` example only guarantees that the custom script loads before Blazor starts. It doesn't guarantee that awaited promises in the script complete their execution before Blazor starts.
+
> [!NOTE]
> MVC and Razor Pages apps don't automatically load JS initializers. However, developer code can include a script to fetch the app's manifest and trigger the load of the JS initializers.
@@ -72,6 +74,94 @@ For an examples of JS initializers, see the following resources:
[!INCLUDE[](~/includes/aspnetcore-repo-ref-source-links.md)]
+### Ensure libraries are loaded in a specific order
+
+Append custom scripts to the `` in `beforeStart` and `afterStarted` in the order that they should load.
+
+The following example loads `script1.js` before `script2.js` and `script3.js` before `script4.js`:
+
+```javascript
+export function beforeStart(options, extensions) {
+ var customScript1 = document.createElement('script');
+ customScript1.setAttribute('src', 'script1.js');
+ document.head.appendChild(customScript1);
+
+ var customScript2 = document.createElement('script');
+ customScript2.setAttribute('src', 'script2.js');
+ document.head.appendChild(customScript2);
+}
+
+export function afterStarted(blazor) {
+ var customScript1 = document.createElement('script');
+ customScript1.setAttribute('src', 'script3.js');
+ document.head.appendChild(customScript1);
+
+ var customScript2 = document.createElement('script');
+ customScript2.setAttribute('src', 'script4.js');
+ document.head.appendChild(customScript2);
+}
+```
+
+### Import additional modules
+
+Use top-level [`import`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/import) statements in the JS initializers file (`*.lib.module.js`) to import additional modules.
+
+`additionalModule.js`:
+
+```javascript
+export function logMessage() {
+ console.log('logMessage is logging');
+}
+```
+
+```javascript
+import { logMessage } from "/additionalModule.js";
+
+export function beforeStart(options, extensions) {
+ ...
+
+ logMessage();
+}
+```
+
+For browser compatibility, see [Can I use: JavaScript statement: import](https://caniuse.com/?search=JavaScript%20statement%3A%20import).
+
+[Dynamic import with the `import()` operator](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/import) is supported with ASP.NET Core and Blazor:
+
+```javascript
+import("additionalModule.js");
+```
+
+For browser compatibility, see [Can I use: JavaScript modules: dynamic import](https://caniuse.com/es6-module-dynamic-import).
+
+### Export additional JavaScript in the JavaScript initializers file
+
+Because the JS initializers file (`*.lib.module.js`) is an ordinary ES6 module, exporting additional JS side-by-side with `beforeStart` and `afterStarted` is supported:
+
+```javascript
+export function beforeStart(options, extensions) {
+ ...
+}
+
+export function afterStarted(blazor) {
+ ...
+}
+
+export function customFunction() {
+ ...
+}
+```
+
+### Import map
+
+[Import maps](https://developer.mozilla.org/docs/Web/HTML/Element/script/type/importmap) are supported by ASP.NET Core and Blazor.
+
+For browser compatibility, see [Can I use: import maps](https://caniuse.com/import-maps).
+
+### Module extension (`.js`/`.mjs`)
+
+Both `.js` and `.mjs` module extensions are supported by ASP.NET Core and Blazor, which are sent with a MIME type of `text/javascript`.
+
:::moniker-end
## Initialize Blazor when the document is ready
@@ -112,9 +202,13 @@ To perform additional tasks, such as JS interop initialization, use [`then`](htt
The `{webassembly|server}` placeholder in the preceding markup is either `webassembly` for a Blazor WebAssembly app (`blazor.webassembly.js`) or `server` for a Blazor Server app (`blazor.server.js`).
+:::moniker range=">= aspnetcore-6.0"
+
> [!NOTE]
> For a library to automatically execute additional tasks after Blazor has started, use a [JavaScript initializer](#javascript-initializers). Use of a JS initializer doesn't require the consumer of the library to chain JS calls to Blazor's manual start.
+:::moniker-end
+
## Load boot resources
*This section only applies to Blazor WebAssembly apps.*
diff --git a/aspnetcore/blazor/javascript-interoperability/index.md b/aspnetcore/blazor/javascript-interoperability/index.md
index 83db20b73aec..0362d51419c9 100644
--- a/aspnetcore/blazor/javascript-interoperability/index.md
+++ b/aspnetcore/blazor/javascript-interoperability/index.md
@@ -190,6 +190,8 @@ JS isolation provides the following benefits:
* Imported JS no longer pollutes the global namespace.
* Consumers of a library and components aren't required to import the related JS.
+Both `.js` and `.mjs` module extensions are supported by ASP.NET Core and Blazor, which are sent with a MIME type of `text/javascript`.
+
For more information, see .
## Cached JavaScript files
@@ -388,6 +390,8 @@ JS isolation provides the following benefits:
* Imported JS no longer pollutes the global namespace.
* Consumers of a library and components aren't required to import the related JS.
+Both `.js` and `.mjs` module extensions are supported by ASP.NET Core and Blazor, which are sent with a MIME type of `text/javascript`.
+
For more information, see .
## Cached JavaScript files
@@ -577,6 +581,8 @@ JS isolation provides the following benefits:
* Imported JS no longer pollutes the global namespace.
* Consumers of a library and components aren't required to import the related JS.
+Both `.js` and `.mjs` module extensions are supported by ASP.NET Core and Blazor, which are sent with a MIME type of `text/javascript`.
+
For more information, see .
## Cached JavaScript files
From 411391f526fd9830268d4efd28f3e2f73f81c28c Mon Sep 17 00:00:00 2001
From: guardrex <1622880+guardrex@users.noreply.github.com>
Date: Fri, 24 Feb 2023 13:32:13 -0600
Subject: [PATCH 2/9] Updates
---
aspnetcore/blazor/fundamentals/startup.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/aspnetcore/blazor/fundamentals/startup.md b/aspnetcore/blazor/fundamentals/startup.md
index 6fec6b1a5bd4..ee2673f3f021 100644
--- a/aspnetcore/blazor/fundamentals/startup.md
+++ b/aspnetcore/blazor/fundamentals/startup.md
@@ -129,7 +129,7 @@ For browser compatibility, see [Can I use: JavaScript statement: import](https:/
[Dynamic import with the `import()` operator](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/import) is supported with ASP.NET Core and Blazor:
```javascript
-import("additionalModule.js");
+import("/additionalModule.js");
```
For browser compatibility, see [Can I use: JavaScript modules: dynamic import](https://caniuse.com/es6-module-dynamic-import).
From 86138c8f9bafeab2fe54f5ddcdf87f0eb0cc99b5 Mon Sep 17 00:00:00 2001
From: guardrex <1622880+guardrex@users.noreply.github.com>
Date: Sat, 25 Feb 2023 04:18:37 -0600
Subject: [PATCH 3/9] Updates
---
aspnetcore/blazor/fundamentals/startup.md | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/aspnetcore/blazor/fundamentals/startup.md b/aspnetcore/blazor/fundamentals/startup.md
index ee2673f3f021..ecae1d952088 100644
--- a/aspnetcore/blazor/fundamentals/startup.md
+++ b/aspnetcore/blazor/fundamentals/startup.md
@@ -12,7 +12,23 @@ uid: blazor/fundamentals/startup
This article explains how to configure Blazor startup.
-The Blazor startup process via the Blazor script (`blazor.{webassembly|server}.js`) is automatic and asynchronous. The Blazor `
+
+
+ }
```
+ In the preceding example, the `{PACKAGE ID/ASSEMBLY NAME}` placeholder of the file name represents the package ID or assembly name of the app.
+
> [!NOTE]
> The call to `registerCustomEventType` is performed in a script only once per event.
+ >
+ > For the call to `registerCustomEventType`, use the `blazor` parameter (lowercase `b`) provided by `afterStarted`. Although the registration is valid when using the `Blazor` object (uppercase `B`), the preferred approach is to use the parameter.
1. Define a class for the event arguments:
@@ -145,7 +151,7 @@ Custom events with custom event arguments are generally enabled with the followi
1. Register the event handler on one or more HTML elements. Access the data that was passed in from JavaScript in the delegate handler method:
```razor
- @using BlazorSample.CustomEvents
+ @using namespace BlazorSample.CustomEvents
@@ -174,6 +180,10 @@ Declare a custom name (`oncustompaste`) for the event and a .NET class (`CustomP
`CustomEvents.cs`:
```csharp
+using Microsoft.AspNetCore.Components;
+
+namespace BlazorSample.CustomEvents;
+
[EventHandler("oncustompaste", typeof(CustomPasteEventArgs),
enableStopPropagation: true, enablePreventDefault: true)]
public static class EventHandlers
@@ -187,24 +197,29 @@ public class CustomPasteEventArgs : EventArgs
}
```
-Add JavaScript code to supply data for the subclass. In the `wwwroot/index.html` or `Pages/_Host.cshtml` file, add the following `
+}
```
+In the preceding example, the `{PACKAGE ID/ASSEMBLY NAME}` placeholder of the file name represents the package ID or assembly name of the app.
+
+> [!NOTE]
+> For the call to `registerCustomEventType`, use the `blazor` parameter (lowercase `b`) provided by `afterStarted`. Although the registration is valid when using the `Blazor` object (uppercase `B`), the preferred approach is to use the parameter.
+
The preceding code tells the browser that when a native [`paste`](https://developer.mozilla.org/docs/Web/API/Element/paste_event) event occurs:
* Raise a `custompaste` event.
@@ -223,6 +238,7 @@ In a Razor component, attach the custom handler to an element.
```razor
@page "/custom-paste-arguments"
+@using BlazorSample.CustomEvents