Use Framework SourceType for WASM pass-through assets in multi-client solutions#125309
Use Framework SourceType for WASM pass-through assets in multi-client solutions#125309lewing wants to merge 1 commit intodotnet:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR addresses a build-time crash in multi-Blazor-WASM-client solutions caused by duplicate StaticWebAsset Identity values when multiple projects reference the same runtime pack files from the NuGet cache. It does so by copying “pass-through” runtime assets into a per-project intermediate directory so each project’s asset Identity resolves to a unique on-disk path.
Changes:
- Identify WebCil candidates that aren’t already produced under the project’s
$(IntermediateOutputPath)webcil/folder. - Copy those pass-through files into
$(_WasmBuildWebcilPath)to ensure per-project uniqueness. - Re-add the copied items as WebCil candidates and track the copied outputs in
FileWrites.
...nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets
Show resolved
Hide resolved
b36f57f to
965b95e
Compare
965b95e to
6c3122c
Compare
...nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets
Outdated
Show resolved
Hide resolved
...nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets
Outdated
Show resolved
Hide resolved
|
After further analysis and feedback, the SDK-only approach is the better fix. Created dotnet/sdk#53328 which handles duplicate Identity in The copy-based approach in this PR re-introduces the staleness problem that #124125 was fixing — if the runtime pack changes on incremental build and Planning to close this PR in favor of the SDK fix. |
javiercn
left a comment
There was a problem hiding this comment.
Copying locally is the right approach for the time being. We shouldn't include multiple conflicting definitions of the same asset in the pipeline.
… solutions
When multiple Blazor WebAssembly client projects reference the same runtime pack,
pass-through files (JS, maps, ICU data, native wasm) share a NuGet cache path.
This causes duplicate Identity keys in the static web assets pipeline, crashing
DiscoverPrecompressedAssets with an ArgumentException.
Instead of copying pass-throughs to the intermediate output path (which risks staleness
on incremental builds when the runtime pack changes), materialize them to a per-project
obj/fx/{PackageId}/ directory using the Framework SourceType convention from the SWA SDK.
This gives each project a unique Identity while properly modeling the relationship:
these are framework assets adopted by each consuming project.
- Pass-through files: copied to obj/fx/{PackageId}/, registered with SourceType=Framework
- WebCil-converted files: remain in obj/webcil/, registered with SourceType=Computed
- Satellite assemblies: placed in culture subdirectories in both cases
- Both groups get per-item ContentRoot for correct Identity resolution
Requires SDK support for SourceType=Framework (dotnet/sdk#53135).
Fixes duplicate-key crash introduced by dotnet#124125.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
6c3122c to
31070bb
Compare
|
Updated to use Javier's preferred approach: Framework SourceType (from dotnet/sdk#53135) instead of the copy-to-intermediate pattern. What changedPass-through files are now materialized to Why this is better than the previous approach
Validation
DependencyThis PR requires dotnet/sdk#53135 to be merged first (adds |
|
Closing in favor of #125329 which is a clean PR for the Framework SourceType approach. This PR's branch was force-pushed over and no longer has the original copy-based approach history. |
Summary
When multiple Blazor WebAssembly client projects reference the same runtime pack, pass-through files (JS, maps, ICU data, native wasm) share a NuGet cache path. This causes duplicate Identity keys in the static web assets pipeline, crashing
DiscoverPrecompressedAssetswith anArgumentExceptiononToDictionary.Root Cause
PR #124125 correctly changed WASM
ContentRootfrom project-specificOutputPathcopies to per-item%(RootDir)%(Directory)(pointing to the real file in the NuGet cache). This fixed staleness on incremental builds. However, when two WASM client projects reference the same runtime pack, shared files likedotnet.js.mapnow resolve to identical NuGet cache paths, producing duplicate Identity values.Fix
Instead of copying pass-throughs to the intermediate output path (which risks re-introducing the staleness bug #124125 fixed), materialize them to a per-project
obj/fx/{PackageId}/directory using the Framework SourceType convention from the SWA SDK (dotnet/sdk#53135).obj/fx/{PackageId}/, registered withSourceType="Framework"obj/webcil/, registered withSourceType="Computed"(already per-project)ContentRootfor correct Identity resolutionArchitecture
This follows the SWA Framework materialization pattern: framework assets are "adopted" by each consuming project, giving them unique per-project Identity values while properly modeling the ownership relationship.
AssetMode=CurrentProjectprevents assets from leaking to references.Dependencies
Requires SDK support for
SourceType="Framework"from dotnet/sdk#53135.Testing
Validated with:
WasmEnableWebcil=false): ✅ All files as Framework pass-throughsRelated