[release/11.0-preview6] [Blazor] Fix WebView blazor.modules.json publish crash via conditional fallback (#67374)#67401
Conversation
Microsoft.AspNetCore.Components.WebView shipped its fallback blazor.modules.json via a static web asset group (BlazorWebViewModules=fallback) plus manifest-promotion targets. At publish, group filtering runs with SkipDeferred=true, so the fallback was not excluded and GenerateStaticWebAssetEndpointsManifest saw two AssetKind=All assets on _framework/blazor.modules.json, throwing 'Sequence contains more than one element' in MAUI Blazor Hybrid apps that also reference a JS-module-contributing RCL. Model blazor.modules.json as a framework static web asset (like Microsoft.AspNetCore.Components.WebAssembly ships its JS): BasePath '/', assets under wwwroot/_framework/, and StaticWebAssetFrameworkPattern '**/*.js;**/*.modules.json'. The framework pattern is matched against the fingerprinted relative path, so a suffix glob (*.modules.json) is required for the JS module manifest to be classified as a Framework asset. The deferred BlazorWebViewModules group + promotion targets are removed; a minimal StaticWebAssets.Groups.targets keeps JSModuleManifestRelativePath and CompressionEnabled for consumers. Add a test project that cracks the built .nupkg files and asserts the static web assets layout/shape for the WebView, WebAssembly, App.Internal.Assets and Identity.UI packages, plus end-to-end build/publish tests that reference the locally-built WebView package from a generated app (and a JS-module RCL) and validate the produced endpoints. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ests The framework-asset modeling of blazor.modules.json/blazor.webview.js broke publish for in-repo projects that reference the WebView project via ProjectReference (the WebView E2E test and the Photino sample): the SDK applies StaticWebAssetFrameworkPattern when computing a referenced project's BUILD static web assets but not its PUBLISH assets, so publish ends up with both the materialized framework asset (SourceType=Discovered, SourceId=consumer) and the original (SourceType=Project, SourceId=WebView) at the same _framework/... target path and fails with 'Conflicting assets with the same target path'. Add a no-op-for-package-consumers workaround in StaticWebAssets.Groups.targets that drops the redundant Project-sourced WebView framework assets at publish (the materialized copies are the ones served), and import the groups targets from the WebView E2E test so it (like the Photino sample) also gets JSModuleManifestRelativePath. Package consumers receive these assets as SourceType=Package, so nothing is removed for them. Test improvements: - Build-behavior tests now create working folders under artifacts/tmp instead of the system temp folder. - Each build/publish captures a binary log under artifacts/log so CI collects it and failures can be diagnosed; the working folder is preserved on failure and removed on success. - Tests log the dotnet invocation, output and binlog path via ITestOutputHelper. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ork assets Adds Publish_ProjectReferenceToWebViewWithJsModuleRcl_SucceedsWithSingleModulesManifest, which references the WebView source project (not the package) plus a JS-module RCL and runs 'dotnet publish'. This is the exact in-repo scenario that regressed in CI: without the StaticWebAssets.Groups.targets workaround it fails with 'Conflicting assets with the same target path _framework/blazor.modules.json'. The test asserts publish succeeds, a single _framework/blazor.modules.json endpoint is produced, and the app's generated manifest (with the RCL module) supersedes the WebView fallback. ConsumerBuild gains an isolateNuGetFeeds option so P2P builds inherit the repo NuGet.config (needed to build the referenced source project) instead of the isolated package feed used by the PackageReference tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…otnet/sdk#54941) Reverts the framework-asset modeling and the in-package publish workaround. With the SDK fix in dotnet/sdk#54941 (resolved deferred static web asset groups are persisted into the build manifest and re-applied, unscoped, when the manifest is reloaded at publish), the idiomatic deferred-group authoring that the WebView package already uses is correct end-to-end: blazor.modules.json is a Package static web asset in the deferred BlazorWebViewModules group, resolved to drop the fallback when the app contributes its own JS modules and keep it otherwise. No framework-asset hack and no package-local workaround are needed, so the WebView product files are unchanged from main. This PR now contributes the static web assets packaging + build/publish regression tests: - Package-layout tests assert the deferred-group shape for WebView (modules.json = Package in BlazorWebViewModules=fallback; webview.js = Framework) and the framework/group shapes for Components.WebAssembly, App.Internal.Assets and Identity.UI. - Build/publish behavior tests (package consumer and ProjectReference consumer) assert a single _framework/blazor.modules.json endpoint and that the app's manifest supersedes the fallback. The publish assertions are skipped until dotnet/sdk#54941 is in the repo SDK (detected via the pre-fix 'Sequence contains more than one element' crash) so the suite stays green meanwhile. Note: this PR depends on dotnet/sdk#54941 flowing into the repo SDK; until then the in-repo WebView publish path (and the publish tests) require that fix. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
#67374) The WebView package ships a fallback _framework/blazor.modules.json (empty []) for apps that contribute no JS library modules. Modeling it as a deferred static web asset group required tagging/promoting the consumer's SDK-generated manifest and depended on an SDK fix (dotnet/sdk#54941) to filter the group at publish; without it, publish crashed with "Sequence contains more than one element" (#67374). Replace the group authoring with conditional materialization: the package ships the fallback raw under build/ (not as a flowing static web asset) and materializes it as the consumer's own asset during ResolveStaticWebAssetsInputs ONLY when the app has no JS modules of its own. The decision runs before the build manifest / conflict check, so exactly one asset ever lands on _framework/blazor.modules.json and there is never a conflict at build or publish. No asset groups, no consumer manifest tagging, no SDK dependency. Tests validate the package layout and build/publish behavior (package + P2P consumers, with and without JS modules) by cracking the built .nupkg and running isolated consumer builds under artifacts/ with binlog capture. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Verified this one locally and it holds up — sharing the evidence since it ended up being a clean repro. I took the minimal repro (Razor-SDK app → WebView package + an RCL with a JS library module) and swapped only the package on the same SDK that crashes with the public preview6 build:
So the package-only approach fixes it with no SDK change, which I think is the better call. Also checked the no-modules case (one route, One edge I hit that the new tests don't cover, flagging as non-blocking: if an app and an RCL both directly reference the WebView package and neither contributes a JS module, each project independently materializes its own |
|
/ba-g quarantine failure |
Backport of #67375 to release/11.0-preview6
/cc @javiercn
[Blazor] Fix WebView blazor.modules.json publish crash via conditional fallback (#67374)
Summary of the changes (Less than 80 chars)
Description
{Detail}
Fixes #{bug number} (in this specific format)
Customer Impact
{Justification}
Regression?
[If yes, specify the version the behavior has regressed from]
Risk
[Justify the selection above]
Verification
Packaging changes reviewed?
When servicing release/2.3