-
Notifications
You must be signed in to change notification settings - Fork 10.3k
[Blazor] Add IRazorComponentsBuilder.AddWebAssemblyComponents()
#48664
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
src/Components/WebAssembly/Server/src/Microsoft.AspNetCore.Components.WebAssembly.Server.csproj
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approving because it's clear this is close to being ready and you can decide for yourself whether it's right to swap around the dependency direction as per my comment.
Also I think we're now at a point where the E2E tests for Endpoint rendering could be extended to include some cases where we insert interactive Server/WebAssembly components and observe that they are actually interactive. Since we already have the core structure for those E2E tests (i.e., there's an app, and the tests know how to start it, etc.) it might not be a massive amount of extra work to introduce one or two tests to show interactivity is possible now. Would you consider that? If you feel it's outside the scope of what you want to handle here that's fine - we just have to get to that at some point :)
/// <summary> | ||
/// Options to configure interactive WebAssembly components in a razor components application. | ||
/// </summary> | ||
public sealed class WebAssemblyComponentsEndpointOptions | ||
{ | ||
/// <summary> | ||
/// Gets or sets <see cref="PathString"/> that indicates the prefix for Blazor WebAssembly framework files. | ||
/// </summary> | ||
public PathString FrameworkFilesPathPrefix { get; set; } | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This API allows the path prefix passed to UseBlazorFrameworkFiles
to be configurable in a "full-stack Blazor"-style app.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this something we could avoid?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the reason for wanting to avoid it? Is it to keep the API smaller for the initial release? Without this API, I don't think there's a way for customers to configure the path prefix passed to UseBlazorFrameworkFiles()
. I was using this API in our own test app so that Components.TestServer
could reference both BasicTestApp
as well as a new, minimal WebAssembly project.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems reasonable to allow this configurability if it's what's need to host multiple independent WebAssembly apps on a single server app.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the naming though, I was a bit misled at first since I thought this would be the path to the _framework
directory (inclusive), whereas from the implementation I see it's the path prefix before the _framework
directory.
What if this were renamed to PathPrefix
or StaticAssetsPathPrefix
?
Also, does this affect the path at which we host the wwwroot
content from a referenced WebAssembly project?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This only impacts the path from which _framework
folder content is loaded. The paths from which wwwroot
content gets served can be configured with UseStaticFiles()
.
I'm worried PathPrefix
might not be clear enough in the context of calling AddWebAssemblyComponents()
. I think StaticAssetsPathPrefix
is a bit too general given that it's specifically _framework
files that we're configuring.
Although, I can't think of a case where the _framework
path prefix would be different than the path prefix for wwwroot
content. So maybe it's okay to go with StaticAssetsPathPrefix
? But maybe then there could still be some confusion around whether calling UseStaticFiles()
is still necessary.
Perhaps we keep the current name but update the XML comment to make this clearer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It also affects _content
, doesn't it? Or if not I think that would be at risk of clashing. And possibly any other framework-supplied files such as hot reload scripts, though I'm not so sure about that.
I don't feel strongly about the name, so if you think FrameworkFilesPathPrefix
is the safest choice in terms of accuracy and understandability, that's fine with me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could totally be missing something, but from what I can tell it looks like _content
isn't affected by this:
Line 37 in 2971950
builder.MapWhen(ctx => ctx.Request.Path.StartsWithSegments(pathPrefix, out var rest) && rest.StartsWithSegments("/_framework") && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's do PathPrefix
for now - one could make the argument that the fact that it only affects _framework
files is an uninteresting detail to the developer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could totally be missing something, but from what I can tell it looks like _content isn't affected by this:
Is that a bug then? I thought the scenario here was "hosting unrelated WebAssembly apps on separate paths". If that's the case we can't have them both using /_content
.
.AddWebAssemblyComponents(options => | ||
{ | ||
options.FrameworkFilesPathPrefix = "/WasmMinimal"; | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is so that we don't inherit the baggage from BasicTestApp
when all we need is a super minimal WebAssembly app to enable WebAssembly interactivity.
using System.Reflection; | ||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting; | ||
|
||
Assembly.Load(nameof(TestContentPackage)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without this, the TestContentPackage
assembly does not get loaded, and RootComponentTypeCache
can't discover the component.
Would we consider updating RootComponentTypeCache
to attempt to load an assembly if it couldn't be found?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is very interesting. Is this just a quirk of the framework that is already the case in .NET 7? For example, if you used <component ... render-mode="WebAssembly">
(as opposed to declaring the root component in Program.cs
) could you get the same issue? My guess is yes.
Rather than block your PR on it, I would recommend filing an issue for us to dig into (unless you think you are actively causing this issue in your PR here, which doesn't appear to be the case to me).
Would we consider updating RootComponentTypeCache to attempt to load an assembly if it couldn't be found?
Assuming you mean code that is actually running on WebAssembly (e.g., inside WebAssemblyHostBuilder
) then yes sure, why not. It's not a security concern in that case.
There could still be a problem since trimming may have removed the component if there was no statically-observable evidence that it was going to be used. However in practice that would be uncommon since we don't trim user assemblies by default. This may change in the future.
...tassets/Components.TestServer/RazorComponents/Components/WebAssemblyInteractiveCounter.razor
Outdated
Show resolved
Hide resolved
Thanks for the feedback, @SteveSandersonMS! I've added some basic E2E tests to validate interactivity. I'm re-requesting a review because I've added some new APIs since you last looked (and brought |
/// <param name="builder">The <see cref="IRazorComponentsBuilder"/>.</param> | ||
/// <param name="configure">A callback to configure <see cref="WebAssemblyComponentsEndpointOptions"/>.</param> | ||
/// <returns>An <see cref="IRazorComponentsBuilder"/> that can be used to further customize the configuration.</returns> | ||
public static IRazorComponentsBuilder AddWebAssemblyComponents(this IRazorComponentsBuilder builder, Action<WebAssemblyComponentsEndpointOptions>? configure = null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this not go on Webassembly.Server
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I initially put it in WebAssembly.Server
because it's consistent with how AddServerComponents
is in Components.Server
, and inverting the direction of the dependency requires moving WebAssembly.Server
into the shared framework.
Does this align with your thinking, or was there another reason you think it belongs in WebAssembly.Server
, @javiercn?
Hard to see how the CI failure in |
`Http2WebSocketTests.HEADERS_Received_SecondRequest_ConnectProtocolReset` failed in #48664
`Http2WebSocketTests.HEADERS_Received_SecondRequest_ConnectProtocolReset` failed in #48664
I can't figure out why @wtgodbe Do you know why this could be happening? Edit: For context, I added
( |
Some of our custom reference resolution logic is turned off for source build, so it may be referencing an older version of the project. The source build binlog will probably contain useful info about what's getting resolved here. @MichaelSimons is this the kind of situation we've used source build patches for in the past? |
Taking a cursory look, the WebAssembly components where it looks like UseBlazorFrameworkFiles is defined are excluded from SourceBuild - https://github.com/dotnet/aspnetcore/blob/main/src/Components/WebAssembly/Directory.Build.props.
No |
I've moved @SteveSandersonMS @javiercn Do you think this is good to merge? |
src/Components/WebAssembly/Server/src/RazorComponentsBuilderExtensions.cs
Show resolved
Hide resolved
src/Components/Endpoints/src/DependencyInjection/WebAssemblyComponentsEndpointOptions.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great!
…mponentsEndpointOptions.cs Co-authored-by: Steve Sanderson <[email protected]>
Add
IRazorComponentsBuilder.AddWebAssemblyComponents()
Adds the
IRazorComponentsBuilder.AddWebAssemblyComponents()
extension method. This allows Blazor WebAssembly components to be rendered from a Blazor app that utilizes SSR.Fixes #46354