Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[browser] Generate boot config as javascript module #112947

Merged
merged 20 commits into from
Mar 4, 2025
Merged

Conversation

maraf
Copy link
Member

@maraf maraf commented Feb 26, 2025

This is a first part of dotnet/aspnetcore#59456.
The goal is to still produce blazor.boot.json by default, but allow to opt-in for javascript module generation. The schema of the javascript module will change in future PR, for now just moving the JSON to JS.
The PR contains a temporal way (window["__DOTNET_INTERNAL_BOOT_CONFIG_SRC"] or <html data-DOTNET_INTERNAL_BOOT_CONFIG_SRC="">) to tweak default boot config location for feature opt-in in tests when the PR flows to other repos

@maraf maraf added arch-wasm WebAssembly architecture area-Build-mono os-browser Browser variant of arch-wasm labels Feb 26, 2025
@maraf maraf added this to the 10.0.0 milestone Feb 26, 2025
@maraf maraf self-assigned this Feb 26, 2025
@maraf
Copy link
Member Author

maraf commented Feb 26, 2025

/azp run runtime

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@maraf
Copy link
Member Author

maraf commented Feb 26, 2025

/azp run runtime

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

PR Overview

This PR enables an experimental opt‑in for generating the boot configuration as a JavaScript module while continuing to support the default JSON file. Key changes include:

  • Updating the config loading logic (loader/config.ts) to use a global boot config source and adding new functions to fetch or import the boot config.
  • Changing file and option names in several test and build files to switch from "blazor.boot.json" to "boot.js" and updating parsing logic accordingly.
  • Extending type definitions (types/index.ts) to accommodate the possibility of a JavaScript module returning a non‐Response promise.

Reviewed Changes

File Description
src/mono/browser/runtime/loader/config.ts Updated boot config source resolution and added boot config fetch/import functions for JS modules.
src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs Adjusted boot config file name and parsing logic to support boot.js.
src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs Refactored WriteBootJson logic to output a JS module when appropriate.
src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTestsBase.cs Added helper methods to update boot.js reference in HTML files for tests.
src/mono/wasm/Wasm.Build.Tests/BrowserStructures/* Updated BootConfigFileName from "blazor.boot.json" to "boot.js" in various MSBuild options.
src/mono/wasm/Wasm.Build.Tests/WasmRunOutOfAppBundleTests.cs Modified test HTML to include the new boot.js configuration.
src/mono/browser/runtime/types/index.ts Extended LoadBootResourceCallback's return type signature to accept additional promise types.

Copilot reviewed 16 out of 16 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

src/mono/browser/runtime/loader/config.ts:238

  • Ensure the attribute name used to override the boot config (data-dotnet_internal_boot_config_src) is consistent with the global variable usage and across test setups to avoid potential case-sensitive mismatches.
module.configSrc = (globalThis as any)["__DOTNET_INTERNAL_BOOT_CONFIG_SRC"] ?? globalThis.window?.document?.documentElement?.getAttribute("data-dotnet_internal_boot_config_src") ?? "./blazor.boot.json";

Copy link
Member

@pavelsavara pavelsavara left a comment

Choose a reason for hiding this comment

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

should we also change samples and templates ?
what about test-main.js ?

@maraf
Copy link
Member Author

maraf commented Feb 27, 2025

should we also change samples and templates ?
what about test-main.js ?

Templates are not affected and will benefit from it once it's opt-out.
Library tests are using WasmAppBuilder and thus it's not supported there yet. I'll come with something once it's opt-out.

@maraf maraf requested review from pavelsavara and Copilot February 27, 2025 10:31

Choose a reason for hiding this comment

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

PR Overview

This PR enables an opt-in mode for generating the boot configuration as a JavaScript module while still producing the traditional JSON file by default. Key changes include:

  • Updating the configuration loader to support both JSON and JS module formats.
  • Adjusting boot config file name references in multiple locations to handle the new JS module output.
  • Modifying test assets and build options to account for the new boot config file naming.

Reviewed Changes

File Description
src/mono/browser/runtime/loader/config.ts Adds support for JS module boot config and adapts boot config loading logic.
src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs Updates boot config file name handling and parsing for JS modules.
src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs Renames and refactors the boot config generation method to support JS output.
src/mono/wasm/Wasm.Build.Tests/BrowserStructures/MSBuildOptions.cs Changes boot config file name, though its value now differs from other parts of the PR.
src/mono/wasm/Wasm.Build.Tests/BrowserStructures/PublishOptions.cs Updates boot config file name reference.
src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTestsBase.cs Inserts boot config override script into HTML tests with the new file naming.
src/mono/browser/runtime/types/index.ts; src/mono/browser/runtime/loader/assets.ts Update type signatures to support the new BootModule callback return type.
src/mono/wasm/Wasm.Build.Tests/WasmRunOutOfAppBundleTests.cs Ensures that updated boot config references are used in the test HTML.

Copilot reviewed 17 out of 17 changed files in this pull request and generated no comments.

Comments suppressed due to low confidence (2)

src/mono/wasm/Wasm.Build.Tests/BrowserStructures/MSBuildOptions.cs:25

  • BootConfigFileName is set to "dotnet.boot.js" here, while other parts of the PR reference "boot.js"; please unify the boot config file name across the codebase.
string                          BootConfigFileName              = "dotnet.boot.js",

src/mono/wasm/Wasm.Build.Tests/BrowserStructures/PublishOptions.cs:29

  • The BootConfigFileName is set to "boot.js" in PublishOptions, which is inconsistent with the "dotnet.boot.js" used elsewhere; consider standardizing the boot config file name.
string BootConfigFileName                                   = "boot.js",
loadedConfigResponse = await fetchBootConfig(appendUniqueQuery(defaultConfigSrc, "manifest"));
loadedConfig = await readBootConfigResponse(loadedConfigResponse);
} else {
loadedConfig = (await import(appendUniqueQuery(defaultConfigSrc, "manifest"))).config;
Copy link
Member

Choose a reason for hiding this comment

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

Is this because we are letting people control where blazor.boot.json was being loaded from?

Copy link
Member Author

Choose a reason for hiding this comment

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

Exactly

Copy link
Member

Choose a reason for hiding this comment

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

@maraf is there a need for us to support that moving forward?

What scenario do we think still mandates we keep this around.

I'm saying this because the more we can simplify this process the better.

Caching and all those things we are handling through the importmap work we did, and I can't really see a reason for this being loaded from elsewhere

Copy link
Member

Choose a reason for hiding this comment

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

I think this could be in use by non-blazor customers, but I don't have anything specific

Copy link
Member Author

@maraf maraf Feb 27, 2025

Choose a reason for hiding this comment

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

What was the original motivation? Modifying the URLs to point to some CDN or subpath on the server is still valid.
This callback processes all framework assets, not just JS modules

Copy link
Member

Choose a reason for hiding this comment

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

Yes, the original motivation was for letting people control the URLs of the deployed app, when we had issues with the anti-virus.

I think it's still fine for things that are "data" like the webcil, but is there a reason why we couldn't rely on relative paths for the module bits? After all, you can already change these urls during the build process modifying the relative paths of the respective assets.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't have a strong opinion. Since blazor users can configure .NET runtime through a callback on Blazor.start, they have all the flexibility to define the assets and their URLs in a defferent way than through the loadResource callback, on the other it's a breaking change.

Comment on lines +597 to +603
var serializer = new DataContractJsonSerializer(
typeof(BootJsonData),
new DataContractJsonSerializerSettings { UseSimpleDictionaryFormat = true });

var config = (BootJsonData?)serializer.ReadObject(stream);
Assert.NotNull(config);
return config;
Copy link
Member

Choose a reason for hiding this comment

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

Is there a reason why you aren't using S.T.J?

Copy link
Member Author

Choose a reason for hiding this comment

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

I dunno. This code was probably inspired by the similar on SDK tests. I'll try to use S.T.J in follow up

Copy link
Member

@javiercn javiercn left a comment

Choose a reason for hiding this comment

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

Looks great!

I have two open questions, but we can address them in a follow-up:

  • Getting rid of the old boot.json path in the runtime file(s). For 9.0 we should only use dotnet.boot.js
  • Doing a top-level import for the dotnet.config.js instead of it being updatable. You can already choose the URLs at build time specifying a relative path, and the import can also be relative to the root of the dotnet.js file.
  • Also, do we think we can get rid of the assets cache now? Or is that a separate item?

@maraf
Copy link
Member Author

maraf commented Feb 28, 2025

Getting rid of the old boot.json path in the runtime file(s). For 9.0 we should only use dotnet.boot.js

The goal is to have only dotnet.boot.js for .NET 10+.

Doing a top-level import for the dotnet.config.js instead of it being updatable. You can already choose the URLs at build time specifying a relative path, and the import can also be relative to the root of the dotnet.js file.

We had customers (non blazor) that were interested in not having a boot config as a separate file and configure it manually. I plan to experiment with defining all the modules as static imports to see how it plays with JS bundlers.

Also, do we think we can get rid of the assets cache now? Or is that a separate item?

Yes, I believe we can remove the cache in a separate task

@maraf maraf merged commit bb146ad into dotnet:main Mar 4, 2025
30 of 33 checks passed
@maraf maraf deleted the BootJs branch March 4, 2025 13:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arch-wasm WebAssembly architecture area-Build-mono os-browser Browser variant of arch-wasm
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants