[release/10.0.3xx] Backport #52816#52881
Conversation
Co-authored-by: Marek Fišera <mara@neptuo.com>
There was a problem hiding this comment.
Pull request overview
Backport to release/10.0.3xx of the WebAssembly Hot Reload embedding work to avoid duplicate static web asset identities when multiple Blazor WASM clients are hosted by a single server, and to remove version unpredictability from NuGet-based Hot Reload assets.
Changes:
- Embed the
Microsoft.DotNet.HotReload.WebAssembly.Browserassets into the WebAssembly SDK layout and define the JS module as a project-scoped static web asset by copying it into$(IntermediateOutputPath)hotreload\. - Update static web assets baselines/tests to reflect the new asset source/paths and add a new
${WebAssemblySdkPath}templatization token for stable baselines. - Adjust Helix test execution scripts and a couple of test asset
launchSettings.jsonfiles.
Reviewed changes
Copilot reviewed 27 out of 27 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| test/TestAssets/TestProjects/WatchBlazorWasmHosted/blazorhosted/Properties/launchSettings.json | Use correct boolean type for dotnetRunMessages in test asset launch settings. |
| test/TestAssets/TestProjects/WatchBlazorWasm/Properties/launchSettings.json | Use correct boolean type for dotnetRunMessages in test asset launch settings. |
| test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssetsBaselineFactory.cs | Add ${WebAssemblySdkPath} tokenization to stabilize baselines referencing the WebAssembly SDK layout. |
| test/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/StaticWebAssetsBaselines/StaticWebAssets_Publish_Hosted_Works.Publish.files.json | Baseline update for Hot Reload asset relocation/removal from package _content. |
| test/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/StaticWebAssetsBaselines/StaticWebAssets_Publish_DoesNotIncludeXmlDocumentationFiles_AsAssets.Publish.files.json | Baseline update for Hot Reload asset relocation/removal from package _content. |
| test/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/StaticWebAssetsBaselines/StaticWebAssets_PublishMinimal_Works.Publish.files.json | Baseline update for Hot Reload asset relocation/removal from package _content. |
| test/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/StaticWebAssetsBaselines/StaticWebAssets_Build_Hosted_Works.Build.staticwebassets.json | Baseline update reflecting Hot Reload JS module now sourced from project intermediate output and routed under _framework. |
| test/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/StaticWebAssetsBaselines/StaticWebAssets_BuildMinimal_Works.Build.staticwebassets.json | Baseline update reflecting Hot Reload JS module now sourced from project intermediate output and routed under _framework. |
| test/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/StaticWebAssetsBaselines/StaticWebAssets_BuildMinimal_Works.Build.files.json | Baseline update for new intermediate hotreload\ files. |
| test/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/StaticWebAssetsBaselines/Publish_DoesNotGenerateManifestJson_IncludesJSModulesOnBlazorBootJsonManifest.Publish.staticwebassets.json | Baseline update for JS module manifest/endpoints after Hot Reload asset relocation. |
| test/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/StaticWebAssetsBaselines/Publish_DoesNotGenerateManifestJson_IncludesJSModulesOnBlazorBootJsonManifest.Publish.files.json | Baseline update for publish output files after Hot Reload asset relocation. |
| test/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/StaticWebAssetsBaselines/JsModules_Hosted_CanCustomizeBlazorInitialization.Publish.files.json | Baseline update for publish output files after Hot Reload asset relocation. |
| test/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/StaticWebAssetsBaselines/JsModules_CanHaveDifferentBuildAndPublishModules.Publish.staticwebassets.json | Baseline update for manifest/endpoints after Hot Reload asset relocation. |
| test/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/StaticWebAssetsBaselines/JsModules_CanHaveDifferentBuildAndPublishModules.Publish.files.json | Baseline update for publish output files after Hot Reload asset relocation. |
| test/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/StaticWebAssetsBaselines/JsModules_CanCustomizeBlazorInitialization.Publish.staticwebassets.json | Baseline update for manifest/endpoints after Hot Reload asset relocation. |
| test/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/StaticWebAssetsBaselines/JsModules_CanCustomizeBlazorInitialization.Publish.files.json | Baseline update for publish output files after Hot Reload asset relocation. |
| test/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/StaticWebAssetsBaselines/JSModules_ManifestIncludesModuleTargetPaths.Build.staticwebassets.json | Baseline update reflecting Hot Reload JS module now under _framework and intermediate output. |
| test/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/StaticWebAssetsBaselines/Build_DoesNotGenerateManifestJson_IncludesJSModulesOnBlazorBootJsonManifest.Build.staticwebassets.json | Baseline update for build manifest/endpoints after Hot Reload asset relocation. |
| src/WasmSdk/Tasks/Microsoft.NET.Sdk.WebAssembly.Tasks.csproj | Pack Hot Reload tool output into the WebAssembly SDK under hotreload/ and add project reference to build it. |
| src/WasmSdk/Sdk/Sdk.targets | Replace implicit Hot Reload PackageReference behavior with SDK-embedded files, copying the JS module to intermediate output and defining it as a static web asset. |
| src/BuiltInTools/HotReloadAgent.WebAssembly.Browser/Microsoft.DotNet.HotReload.WebAssembly.Browser.csproj | Change to non-Razor SDK project, pin to net10.0, and ensure wwwroot content is copied to output for SDK embedding. |
| build/RunTestsOnHelix.sh | Stop adding $DOTNET_ROOT/.nuget as a NuGet source during Helix test runs. |
| build/RunTestsOnHelix.cmd | Stop adding %DOTNET_ROOT%\.nuget as a NuGet source during Helix test runs. |
src/WasmSdk/Sdk/Sdk.targets
Outdated
| </_WasmHotReloadModule> | ||
| <_WasmHotReloadModule OriginalItemSpec="%(Identity)" /> |
There was a problem hiding this comment.
<_WasmHotReloadModule OriginalItemSpec="%(Identity)" /> is an MSBuild item element without Include/Update/Remove, which will error during evaluation (and it also won’t set OriginalItemSpec on the item created above). Use Update to set the metadata on the existing @(_WasmHotReloadModule) item(s) instead of declaring a new, empty item element.
| </_WasmHotReloadModule> | |
| <_WasmHotReloadModule OriginalItemSpec="%(Identity)" /> | |
| <OriginalItemSpec>%(Identity)</OriginalItemSpec> | |
| </_WasmHotReloadModule> |
build/RunTestsOnHelix.sh
Outdated
| @@ -22,7 +22,6 @@ dotnet new --debug:ephemeral-hive | |||
|
|
|||
| # We downloaded a special zip of files to the .nuget folder so add that as a source | |||
There was a problem hiding this comment.
This comment is now misleading: the script says the special zip was downloaded to $DOTNET_ROOT/.nuget and should be added as a source, but the command that added that source was removed. Please update the comment to match the current behavior (or re-add the source if it’s still required).
| # We downloaded a special zip of files to the .nuget folder so add that as a source | |
| # Add the local test packages directory as a NuGet source for this test run |
build/RunTestsOnHelix.cmd
Outdated
| @@ -36,7 +36,6 @@ dotnet new --debug:ephemeral-hive | |||
| REM We downloaded a special zip of files to the .nuget folder so add that as a source | |||
There was a problem hiding this comment.
This comment is now misleading: it says a special zip was downloaded to %DOTNET_ROOT%\.nuget and should be added as a source, but the command that added that source was removed. Please update the comment to match the current behavior (or re-add the source if it’s still required).
| REM We downloaded a special zip of files to the .nuget folder so add that as a source | |
| REM List current NuGet sources and, if test packages are present, add them as a local source |
|
This needs review from @maraf and probably some fixes around the baselines |
- Fix invalid MSBuild ItemGroup syntax: use Update instead of creating empty item - Update comments in test scripts to reflect actual behavior - Addresses PR review feedback from copilot-pull-request-reviewer
Backport of #52816 to release/10.0.3xx, based on @maraf's PR #52710.
Customer Issue
When multiple Blazor WASM client projects (e.g., FirstClient and SecondClient) are hosted by a single server project, users encounter a duplicate key error in
FilterStaticWebAssetEndpoints. Both clients define the same HotReload JS module (Microsoft.DotNet.HotReload.WebAssembly.Browser.lib.module.js) as a static web asset with identical Identity values, causing the build to fail.Additionally, the HotReload assembly version could be unpredictable when pulled from NuGet package sources, leading to potential version conflicts between the SDK and the referenced package.
Users cannot easily workaround these issues without modifying their project structure to use a single Blazor WASM client.
Description
This PR fixes both issues by embedding the HotReload functionality directly in the WebAssembly SDK:
hotreload\before being defined as a StaticWebAssetThis follows the established pattern used by JSModules, ScopedCss, and ServiceWorker targets, and @javiercn's guidance: "What we do in other situations with assets like this is to copy them to the intermediate output folder before defining them."
Was this a regression?
Testing
The
Publish_HostingMultipleBlazorWebApps_Workstest now passes and validates the fix.Risk
Low - this follows established patterns used elsewhere in the SDK for similar assets (JSModules, ScopedCss, ServiceWorker), and the change is well-tested. Embedding in the SDK also eliminates version conflicts.