Skip to content

Commit 965b95e

Browse files
lewingCopilot
andcommitted
Fix duplicate StaticWebAsset Identity crash for multi-WASM-client solutions
PR #124125 changed WASM ContentRoot to per-item %(RootDir)%(Directory), which makes each asset's Identity its real file path on disk. This is correct for single-client scenarios and fixes SRI integrity on incremental builds, but breaks multi-WASM-client solutions: NuGet cache pass-through files (JS, maps, ICU, native wasm) resolve to the same Identity across projects, causing a ToDictionary crash in DiscoverPrecompressedAssets. The fix copies pass-through files from the shared NuGet cache to the per-project $(IntermediateOutputPath)webcil/ directory (where webcil-converted files already live), so every project gets a unique Identity. Satellite assemblies are placed in culture subdirectories to match ConvertDllsToWebcil behavior. This follows the pattern from sdk#52816 and Javier's SWA design principle that Identity should match a real file on disk. Fixes the aspnetcore codeflow regression where solutions hosting multiple Blazor WASM clients fail with: System.ArgumentException: An item with the same key has already been added. Key: ...dotnet.js.map at DiscoverPrecompressedAssets.Execute() Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 8151eb1 commit 965b95e

1 file changed

Lines changed: 32 additions & 0 deletions

File tree

src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,39 @@ Copyright (c) .NET Foundation. All rights reserved.
360360
<Output TaskParameter="FileWrites" ItemName="FileWrites" />
361361
</ConvertDllsToWebcil>
362362

363+
<!-- Copy pass-through files (JS, maps, ICU, native wasm, and when WebCil is disabled, DLLs)
364+
from shared locations (e.g. NuGet cache) to a per-project directory so each project gets
365+
a unique Identity when multiple WASM client projects reference the same runtime pack.
366+
Webcil-converted files already live in per-project $(IntermediateOutputPath)webcil/ and
367+
don't need copying. Satellite assemblies are placed in culture subdirectories to match
368+
ConvertDllsToWebcil behavior. -->
363369
<ItemGroup>
370+
<_WasmPassThroughCandidates Include="@(_WebcilAssetsCandidates)"
371+
Condition="!$([System.String]::new('%(Identity)').StartsWith($(_WasmBuildWebcilPath)))" />
372+
<_WebcilAssetsCandidates Remove="@(_WasmPassThroughCandidates)" />
373+
</ItemGroup>
374+
375+
<!-- Separate satellite (culture) pass-throughs from regular ones so we can place them in subdirs -->
376+
<ItemGroup>
377+
<_WasmCulturePassThroughs Include="@(_WasmPassThroughCandidates)"
378+
Condition="'%(_WasmPassThroughCandidates.AssetTraitName)' == 'Culture'" />
379+
<_WasmPassThroughCandidates Remove="@(_WasmCulturePassThroughs)" />
380+
</ItemGroup>
381+
382+
<Copy SourceFiles="@(_WasmPassThroughCandidates)"
383+
DestinationFolder="$(_WasmBuildWebcilPath)"
384+
SkipUnchangedFiles="true" />
385+
386+
<Copy SourceFiles="@(_WasmCulturePassThroughs)"
387+
DestinationFiles="@(_WasmCulturePassThroughs->'$(_WasmBuildWebcilPath)%(AssetTraitValue)/%(Filename)%(Extension)')"
388+
SkipUnchangedFiles="true"
389+
Condition="'@(_WasmCulturePassThroughs)' != ''" />
390+
391+
<ItemGroup>
392+
<FileWrites Include="@(_WasmPassThroughCandidates->'$(_WasmBuildWebcilPath)%(Filename)%(Extension)')" />
393+
<FileWrites Include="@(_WasmCulturePassThroughs->'$(_WasmBuildWebcilPath)%(AssetTraitValue)/%(Filename)%(Extension)')" />
394+
<_WebcilAssetsCandidates Include="@(_WasmPassThroughCandidates->'$(_WasmBuildWebcilPath)%(Filename)%(Extension)')" />
395+
<_WebcilAssetsCandidates Include="@(_WasmCulturePassThroughs->'$(_WasmBuildWebcilPath)%(AssetTraitValue)/%(Filename)%(Extension)')" />
364396
<!-- Set per-item ContentRoot so each asset's Identity matches its actual file on disk -->
365397
<_WebcilAssetsCandidates Update="@(_WebcilAssetsCandidates)" ContentRoot="%(RootDir)%(Directory)" />
366398
<_WasmFingerprintPatterns Include="WasmFiles" Pattern="*.wasm" Expression="#[.{fingerprint}]!" />

0 commit comments

Comments
 (0)