[browser] Don't copy framework assets to output during build#126407
[browser] Don't copy framework assets to output during build#126407
Conversation
During build, the WebAssembly SDK was copying all .wasm and .js framework assets to bin/wwwroot/_framework/ via CopyToOutputDirectory=PreserveNewest. This is unnecessary because dotnet run uses the static web assets middleware, which serves files directly from their obj/ locations using the manifest. Change CopyToOutputDirectory from PreserveNewest to Never for: - Webcil-converted assets (Computed static web assets) - Materialized framework assets (dotnet.js, dotnet.native.wasm, etc.) This eliminates ~178 file copies during build while preserving correct behavior for dotnet run (static web assets middleware) and publish (CopyToPublishDirectory was already Never). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
|
Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara |
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
With CopyToOutputDirectory=Never, framework assets are no longer copied to bin/wwwroot/_framework/ during build. They are served from obj/ locations via the static web assets middleware during dotnet run. Only assert bundle file layout for publish, where files are still physically copied to the output. Build-time tests that run the app (via dotnet run or xharness) still validate the app works correctly - they just don't check for files in bin/ that are intentionally no longer there. The Blazor-specific AssertBundle already had this guard WasmTemplateTestsBase path needed updating. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
With CopyToOutputDirectory=Never, framework files are no longer copied to bin/_framework/ during build. Update MultiClientHostedBuildAndPublish to assert framework files exist in obj/<config>/<tfm>/fx/<ProjectName>/ _framework/ for build, matching the materialization path used by UpdatePackageStaticWebAssets. Publish assertions remain unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Revert the IsPublish guard that skipped AssertWasmSdkBundle for builds.
Instead, add AssertBuildBundle that validates framework files are in their
correct obj/ subdirectories with CopyToOutputDirectory=Never:
- dotnet.js (boot config) in obj/{config}/{tfm}/
- dotnet.runtime.js, maps, ICU in obj/{config}/{tfm}/fx/{name}/_framework/
- dotnet.native.* in fx/_framework/ (non-native) or wasm/for-build/ (native)
- webcil assemblies in obj/{config}/{tfm}/webcil/
- framework files NOT in bin/_framework/
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…aded worker - Remove accidentally committed WasmAppHost symlink pointing to local Codespace build artifacts path - Add dotnet.native.worker.mjs validation in AssertBuildBundle for multi-threaded build scenarios to match publish-path coverage Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
With framework assets no longer copied to bin/_framework/ during build,
update the three remaining failing tests to look for files in the obj
subdirectories where they actually live:
- Blazor BuildPublishTests.DefaultTemplate_WithResources_Publish:
probe satellite assemblies under obj/{config}/{tfm}/webcil/{locale}/
(webcil) or obj/{config}/{tfm}/fx/{name}/_framework/{locale}/ (non-webcil)
for the build-time assertion.
- BuildPublishTests.BuildThenPublishWithAOT: stat framework files for the
first build from obj/{config}/{tfm}/fx/{name}/_framework/ (JS, source
maps) and obj/{config}/{tfm}/wasm/for-build/ (native outputs). Boot
config is read from obj/{config}/{tfm}/dotnet.js via a new optional
bootConfigDir parameter on GetFilesTable used by fingerprint resolution.
- ModuleConfigTests.SymbolMapFileEmitted(isPublish=false): search for
dotnet.native*.js.symbols in obj/wasm/for-build/ (native rebuild) and
in obj/fx/*/_framework/ as a fallback.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🤖 Copilot Code Review — PR #126407Note This review was AI/Copilot-generated. Models used: Claude Opus 4.6 (primary), Claude Sonnet 4.5. Holistic AssessmentMotivation: The PR addresses a genuine build performance issue — ~178 unnecessary file copies during build. The static web assets middleware already serves files from obj/ locations via the manifest, making the Approach: The approach is clean and minimal — 3 attribute value changes in production code ( Summary: Detailed Findings✅ Production Change — Correct and well-scopedThe three changes in
The updated XML comments (lines 430–435) accurately describe the new behavior. ✅ New
|
Addresses review feedback: centralizes the obj/.../fx/<source-id>/_framework/ discovery logic in WasmSdkBasedProjectProvider.GetMaterializedFrameworkDir and uses it from AssertBuildBundle, BuildPublishTests and Blazor/MiscTests so the per-project fx subdir name is discovered instead of hardcoded. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Apply GetMaterializedFrameworkDir helper to the remaining three locations flagged by the review bot: Blazor/BuildPublishTests GetBuildSatelliteBaseDir, SatelliteLoadingTests, and ModuleConfigTests (the last still inlines the extra 'wasm/for-build' search path but deduplicates the fx-base Path.Combine). - Explain why dotnet.native.worker.mjs is not compared against the runtime pack in AssertBuildBundle (parity with AssertBundle's publish path comment). - Log when AssertWasmSdkBundle skips AssertBuildBundle because NonDefaultFrameworkDir is set, so the coverage gap is visible in test output. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Note Comment authored with assistance from GitHub Copilot. Thanks for the thorough pass. Addressing the findings in 00635ac + c6fe5e5: ✅ Code duplication (5× ✅ ✅ Duplicate ✅ Left as-is:
|
…n obj/fx
With CopyToOutputDirectory=Never, the materialized framework dir under
obj/{config}/{tfm}/fx/{source-id}/_framework/ contains dotnet.runtime.js
under its canonical (non-fingerprinted) name during build. Fingerprinting
is applied later when publishing to bin. GetFilesTable rewrites the entry
from the boot config (which already reflects the publish layout), yielding
a fingerprinted path that does not exist in obj/fx and causes CompareStat
to report the file as missing.
Override the dotnet.runtime.js entry to the unfingerprinted obj/fx path
for the build-phase stat, mirroring the existing native-file override.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
@javiercn Do we have scenario that would still rely on the actual files in the bin folder? |
Run the server via 'dotnet run --no-build' and use Playwright's APIRequestContext to verify that each referenced client's framework files are served from the obj/ materialized directory at the /<client>/_framework/* base path. This guards the hosted scenario from PR #126407 review feedback (build-only, server statically serves client assets). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Note This comment was generated with the assistance of GitHub Copilot. CI analysis for the latest push (build 1388930):
The single failure is This is the well-known Helix Docker-pull infrastructure flake tracked in #117164 — tests never started; the failing test ( |
Note
This PR was created with the assistance of GitHub Copilot.
Summary
During build, the WebAssembly SDK copies all
.wasmand.jsframework assets (~178 files) tobin/wwwroot/_framework/viaCopyToOutputDirectory=PreserveNewest. This is unnecessary becausedotnet runuses the static web assets middleware, which serves files directly from theirobj/locations via the manifest (staticwebassets.runtime.json).Changes
Set
CopyToOutputDirectory=Never(wasPreserveNewest) for threeDefineStaticWebAssets/ item-update calls inMicrosoft.NET.Sdk.WebAssembly.Browser.targets:.wasmfiles produced from.dlldotnet.js,dotnet.native.wasm, runtime JS, etc.UpdatePackageStaticWebAssets) — the per-project copies inobj/fx/Validation
dotnet buildwithTargetOS=browser)dotnet runstarts WasmAppHost dev server correctly42)bin/wwwroot/_framework/drops from ~178 files to 2 (only hot-reload module + dotnet.js from a separate code path)CopyToPublishDirectorywas alreadyNever— publish is unaffectedNotes
PreserveNewestwas added for Blazor WASM hosted scenarios where a server project serves the client's framework files. This scenario needs separate validation.obj/dirs), so physical copies inbin/are not needed fordotnet run.Downstream impact: dotnet/sdk BlazorWasm test baselines
The
Microsoft.NET.Sdk.BlazorWebAssembly.TestsStaticWebAssetsBaselines/*.Build.*.jsonfiles in dotnet/sdk currently assert that framework assets live under${ProjectPath}\bin\Debug\${Tfm}\wwwroot\_framework\after Build. Across the Build baselines there are ~1,940bin\Debugreferences covering ~481 framework files:dotnet.*runtime/loader JS +.wasm+.map(+.gz) — 12 filesicudt_*.dat.gz— 3 filesblazor.webassembly.js(+.gz) — 2 files.wasmassemblies (+.gzcopies).resources.wasmsatellitesOnce this change flows to dotnet/sdk, these baselines will need to be regenerated so framework assets point at their intermediate/
RestorePathlocations instead ofbin\. App-project outputs (blazorwasm.wasm/.pdb) and project references (RazorClassLibrary.*) are unaffected and remain underbin\.