Open amieres opened 5 years ago
A shared _bin
directory would be problematic because of the linker. The build process calls illink
, which strips assemblies of types and methods that aren't used by the main assembly. So if you share _bin
between two pages, one of them is going to hit MissingMethodException
or other similar errors because it's trying to use an assembly that was linked for the other page. I've searched if there was a way to illink
against several entry points, but I didn't find one.
I would say try as much as possible to write these pages in the same assembly and use Bolero routing to switch between them; but if you can't (eg because they have different layout in the static part of the page), then I don't see a better way than making them in completely separate subfolders. If you have an ASP.NET Core server side, you need to put at least one of the UseBlazor
calls in an IApplicationBuilder.Map
:
app
.Map("/page1", fun app -> app.UseBlazor<Page1.Startup>() |> ignore)
.Map("/page2", fun app -> app.UseBlazor<Page2.Startup>() |> ignore)
.UseBlazor<RootPage.Startup>()
|> ignore
@Tarmil
.Map(routePath, initialization)
workflow effectively the equivalent to "mounting a route" in other frameworks (just for clarification)?[<Endpoint "path">]
attribute where a route references a record that that, itself, also has endpoints (so mounting doesn't have to be done at the "app" level)?
- Is this
.Map(routePath, initialization)
workflow effectively the equivalent to "mounting a route" in other frameworks (just for clarification)?
Just to be clear: the .Map(...)
I showed above is a server-side ASP.NET Core feature and completely unrelated to Bolero's routing. And yeah it's pretty much equivalent to mounting a route in other frameworks.
- Based on the custom route workflow in the documentation, it seems like it would be possible to procedurally generate mounted routes, albeit in a verbose manner. Is this correct?
You're talking about "Custom router" in the documentation, right? This is a Bolero feature, so it's client-side and will only trigger if the containing page was returned by the server in the first place.
- Is there a simplified workflow overall for mounting routes using the
[<Endpoint "path">]
attribute where a route references a record that that, itself, also has endpoints (so mounting doesn't have to be done at the "app" level)?
I'm not sure if this is what you mean, but you can combine routes like this:
type SubApp1 =
| [<EndPoint "/page1">]
Page1_1
| [<EndPoint "/page2">]
Page1_2
type SubApp2 =
| [<EndPoint "/page1">]
Page2_1
| [<EndPoint "/page2">]
Page2_2
type FullAppPage =
| [<EndPoint "/sub1/{page}">]
Sub1 of page: SubApp1 // -> /sub1/page1, /sub1/page2
| [<EndPoint "/sub2/{page}">]
Sub1 of page: SubApp2 // -> /sub2/page1, /sub2/page2
- Does this linker problem mean that if I create F# libraries and wish to use them in both my Client and Server Bolero projects, then I will run into issues?
No, this won't cause any problems. The "illinked" assemblies are used on the WebAssembly side, but the original full assemblies will be used by the server side if you reference them from there.
A shared
_bin
directory would be problematic because of the linker. The build process callsillink
, which strips assemblies of types and methods that aren't used by the main assembly. So if you share_bin
between two pages, one of them is going to hitMissingMethodException
or other similar errors because it's trying to use an assembly that was linked for the other page. I've searched if there was a way toillink
against several entry points, but I didn't find one.I would say try as much as possible to write these pages in the same assembly and use Bolero routing to switch between them; but if you can't (eg because they have different layout in the static part of the page), then I don't see a better way than making them in completely separate subfolders. If you have an ASP.NET Core server side, you need to put at least one of the
UseBlazor
calls in anIApplicationBuilder.Map
:app .Map("/page1", fun app -> app.UseBlazor<Page1.Startup>() |> ignore) .Map("/page2", fun app -> app.UseBlazor<Page2.Startup>() |> ignore) .UseBlazor<RootPage.Startup>() |> ignore
This reply is quite old and the startup code has changed a lot since then so I'm not sure how it should look today.
I think I have the same situation. I have an application for creating an SVG graph which is displayed in an <iframe>
element. You can embed the finished graph in an unrelated web page but I don't want this to download the code for the main application, just the code for the displaying the graph. The main application will have a _Host.cshtml file with some static layout and I assume I'll need another _Graph.cshtml with a minimal layout. I'm imagining one server project and two client projects.
Is this how to do it? How should the startup code look?
After some experimentation, here's how to do it.
I have a second client project, called Graph.Client.fsproj and the server has a separate _Graph.cshtml page to render it.
(1) _Graph.cshtml has two changes.
@page "/graph"
<base href="/graph/">
(2) Graph.Client.fsproj has the static web asset base path set so that static resources (css and js) will be found under the base href /graph
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<StaticWebAssetBasePath>graph</StaticWebAssetBasePath>
</PropertyGroup>
(3) Startup.fs in the server project now looks like this:
member _.Configure (app: IApplicationBuilder, env: IWebHostEnvironment) =
app
.UseAuthentication()
.UseRemoting()
.UseBlazorFrameworkFiles()
.UseStaticFiles()
.MapWhen(
(fun ctx -> ctx.Request.Path.Value.StartsWith "/graph"),
(fun app ->
app
.UseBlazorFrameworkFiles(PathString "/graph")
.UseStaticFiles("/graph")
.UseRouting()
.UseEndpoints(fun endpoints ->
endpoints.MapFallbackToPage("/graph/{*path:nonfile}", "/_Graph") |> ignore)
|> ignore
))
.UseRouting()
.UseEndpoints(fun endpoints ->
#if DEBUG
endpoints.UseHotReload()
#endif
endpoints.MapBlazorHub() |> ignore
endpoints.MapFallbackToPage("/_Host") |> ignore)
|> ignore
This all works, but I have a residual issue with Bolero remoting, which is documented here:
https://github.com/fsbolero/Bolero/issues/204
Also, with DotNet SDK version 5.0.102, the published app has an issue, which is documented in the following thread and will be fixed in version 5.0.3. There is a manual patch which fixes the issue until that time.
https://github.com/dotnet/aspnetcore/issues/29179#issuecomment-760404863
What would be the best way to organize several pages that use Bolero. Should we have a shared _bin directory?