Skip to content

[Blazor] Initializers fixes for Blazor Web#50860

Merged
mkArtakMSFT merged 1 commit intorelease/8.0from
javiercn/blazor-web-initializers
Oct 5, 2023
Merged

[Blazor] Initializers fixes for Blazor Web#50860
mkArtakMSFT merged 1 commit intorelease/8.0from
javiercn/blazor-web-initializers

Conversation

@javiercn
Copy link
Copy Markdown
Member

@javiercn javiercn commented Sep 21, 2023

Updates the initializers in Blazor to include platform specific variants that can be tailored to each runtime.

Description

  • Initializers in Blazor WebAssembly and Server allowed library authors and applications to define JS modules that would be automatically imported by the JS Blazor runtime when it booted up.
  • These JS modules were used to tweak the configuration of a given Blazor Runtime or perform additional initialization of JS libraries on the page.
  • Since Blazor Web can have multiple runtimes running simultaneously on the page at the same time (server and webassembly), libraries can run into issues like initializing the wrong runtime, running initialization multiple times, or having to wait until we initialize a runtime to apply custom styles and other logic that might be necessary for the correct function of their libraries.
  • This PR addresses that by defining runtime specific extension points that libraries can use to tweak a concrete runtime when it boots as well as an initial extension point to target Blazor Web specific scenarios that don't involve a runtime.

Fixes #50187

Customer Impact

  • Existing libraries with initializers won't be initialized until an interactive component is rendered on the page.
  • Initialization logic might run more than once for existing libraries, causing all sorts of unpredictable side effects.
    • For example, double initialization.

Regression?

  • Yes
  • No

It's not a regression in the sense that Blazor Web is a new scenario, but a feature that library authors depend on (for example the Fluent UI Blazor components library does) will not work reliably in this scenario.

Risk

  • High
  • Medium
  • Low

The fix is an extension to the existing mechanism to give library authors a path forward. The previous mechanism is disabled by default in Blazor Web scenarios and this fix gives library authors a path forward to make the feature work reliably here. In addition to that, with this fix app developers are not blocked on library authors updating their packages to work on Blazor web, as they can author adapters for the initializers within their apps that use the extension defined by the fix.

Verification

  • Manual (required)
  • Automated

Packaging changes reviewed?

  • Yes
  • No
  • N/A

When servicing release/2.1

  • Make necessary changes in eng/PatchConfig.props

@ghost ghost added area-blazor Includes: Blazor, Razor Components labels Sep 21, 2023
Comment thread src/Components/Web.JS/src/JSInitializers/JSInitializers.Server.ts
@javiercn javiercn force-pushed the javiercn/blazor-web-initializers branch from d9c6241 to 3c8a14c Compare September 22, 2023 15:10
@javiercn javiercn marked this pull request as ready for review September 22, 2023 15:20
@javiercn javiercn requested a review from a team as a code owner September 22, 2023 15:20
Comment on lines +87 to +125
if (beforeWebAssemblyStart) {
options.webAssembly.initializers.beforeStart.push(beforeWebAssemblyStart);
}

if (afterWebAssemblyStarted) {
options.webAssembly.initializers.afterStarted.push(afterWebAssemblyStarted);
}

if (beforeServerStart) {
options.circuit.initializers.beforeStart.push(beforeServerStart);
}

if (afterServerStarted) {
options.circuit.initializers.afterStarted.push(afterServerStarted);
}

if (afterWebStarted) {
jsInitializer.afterStartedCallbacks.push(afterWebStarted);
}

if (beforeWebStart) {
return beforeWebStart(options);
}
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We essentially collect all the callbacks from the initializer for server and webassembly, and set them in their respective options types. After that, we start running the beforeWebStart callback and trigger the afterWebStarted callbacks once we are done with the first render.

@javiercn javiercn force-pushed the javiercn/blazor-web-initializers branch from f5af2d0 to c7e1166 Compare September 22, 2023 20:42
@wtgodbe
Copy link
Copy Markdown
Member

wtgodbe commented Sep 27, 2023

@javiercn if this is still needed it should be retargeted to release/8.0

@javiercn
Copy link
Copy Markdown
Member Author

@wtgodbe I will retarget it once I am done with it.

@javiercn javiercn changed the base branch from release/8.0-rc2 to release/8.0 October 2, 2023 16:03
@javiercn javiercn force-pushed the javiercn/blazor-web-initializers branch 3 times, most recently from 149d4a9 to c8bb94d Compare October 2, 2023 18:44
Copy link
Copy Markdown
Member

@MackinnonBuck MackinnonBuck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still need to go through things in more detail, but the approach looks good to me so far.

Comment thread src/Components/Web.JS/src/Boot.Server.Common.ts
Comment thread src/Components/Web.JS/src/Boot.Server.ts
Comment thread src/Components/Web.JS/src/Boot.Server.Common.ts
@javiercn javiercn added the Servicing-consider Shiproom approval is required for the issue label Oct 2, 2023
@ghost
Copy link
Copy Markdown

ghost commented Oct 2, 2023

Hi @javiercn. Please make sure you've updated the PR description to use the Shiproom Template. Also, make sure this PR is not marked as a draft and is ready-to-merge.

To learn more about how to prepare a servicing PR click here.

@danmoseley
Copy link
Copy Markdown
Member

this has the servicing-consider label but I don't see a mail for it yet.

@javiercn javiercn force-pushed the javiercn/blazor-web-initializers branch 2 times, most recently from 9305ae7 to 7f26317 Compare October 4, 2023 11:08
@javiercn javiercn requested a review from a team as a code owner October 4, 2023 11:08
@javiercn javiercn force-pushed the javiercn/blazor-web-initializers branch from 7f26317 to 3fb8fff Compare October 4, 2023 13:07
@mkArtakMSFT mkArtakMSFT added Servicing-approved Shiproom has approved the issue and removed Servicing-consider Shiproom approval is required for the issue labels Oct 4, 2023
@ghost
Copy link
Copy Markdown

ghost commented Oct 4, 2023

Hi @javiercn. This PR was just approved to be included in the upcoming servicing release. Somebody from the @dotnet/aspnet-build team will get it merged when the branches are open. Until then, please make sure all the CI checks pass and the PR is reviewed.

* Updates initializers support to look for runtime specific callbacks
  * beforeWebStart, afterWebStarted.
  * beforeWebAssemblyStart, afterWebAssemblyStarted
  * beforeServerStarts, afterServerStarted
* There is a new option on Blazor Server to get a callback when a circuit
  is opened and closed in Blazor web scenarios.
* Blazor web applications ignore old initializers by default and warn in
  the console of their presence.
  * Classic initializers can be turned on via a setting in Blazor.start
    options.
* Blazor WebAssembly and Blazor Server applications are updated to prefer
  the new runtime specific initializers over the classic ones, but will
  still run the classic ones by default.
@javiercn javiercn force-pushed the javiercn/blazor-web-initializers branch from 3fb8fff to 7ca18db Compare October 4, 2023 18:22
@mkArtakMSFT mkArtakMSFT merged commit 51f80c7 into release/8.0 Oct 5, 2023
@mkArtakMSFT mkArtakMSFT deleted the javiercn/blazor-web-initializers branch October 5, 2023 15:14
@ghost ghost added this to the 8.0.0 milestone Oct 5, 2023
SteveSandersonMS pushed a commit that referenced this pull request Oct 5, 2023
Updates the initializers in Blazor to include platform specific variants that can be tailored to each runtime.

## Description

* Initializers in Blazor WebAssembly and Server allowed library authors and applications to define JS modules that would be automatically imported by the JS Blazor runtime when it booted up.
* These JS modules were used to tweak the configuration of a given Blazor Runtime or perform additional initialization of JS libraries on the page.
* Since Blazor Web can have multiple runtimes running simultaneously on the page at the same time (server and webassembly), libraries can run into issues like initializing the wrong runtime, running initialization multiple times, or having to wait until we initialize a runtime to apply custom styles and other logic that might be necessary for the correct function of their libraries.
* This PR addresses that by defining runtime specific extension points that libraries can use to tweak a concrete runtime when it boots as well as an initial extension point to target Blazor Web specific scenarios that don't involve a runtime.

Fixes #50187

## Customer Impact

* Existing libraries with initializers won't be initialized until an interactive component is rendered on the page.
* Initialization logic might run more than once for existing libraries, causing all sorts of unpredictable side effects.
  * For example, double initialization.

## Regression?

- [ ] Yes
- [X] No

It's not a regression in the sense that Blazor Web is a new scenario, but a feature that library authors depend on (for example the Fluent UI Blazor components library does) will not work reliably in this scenario.

## Risk

- [ ] High
- [ ] Medium
- [X] Low

The fix is an extension to the existing mechanism to give library authors a path forward. The previous mechanism is disabled by default in Blazor Web scenarios and this fix gives library authors a path forward to make the feature work reliably here. In addition to that, with this fix app developers are not blocked on library authors updating their packages to work on Blazor web, as they can author adapters for the initializers within their apps that use the extension defined by the fix.

## Verification

- [ ] Manual (required)
- [X] Automated

## Packaging changes reviewed?

- [ ] Yes
- [ ] No
- [X] N/A

----

## When servicing release/2.1

- [ ] Make necessary changes in eng/PatchConfig.props
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-blazor Includes: Blazor, Razor Components Servicing-approved Shiproom has approved the issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants