Marvin's Blog【程式人生】

Ability will never catch up with the demand for it

25 Jul 2021

Blazor文档阅读【二】

ASP.NET Core Blazor project structure

Blazor WebAssembly

模板:blazorwasm

  • Pages目录:可路由的组件或页面(.razor),路由通过@page条令给出
    • Counter组件
    • FetchData组件
    • Index组件
  • Properties/launchSettings.json,保存development environment configuration
  • Shared目录
    • MainLayout组件
    • MainLayout.razor.css
    • NavMenu组件,侧边栏导航。包含了NavLink组件
    • NavMenu.razor.css
    • SurveyPrompt组件
  • wwwroot,用于存放应用的公开静态物料,包括appsettings.json,以及index.html(适用于根页面为静态页面的应用)
    • 任何页面请求都会导致返回渲染后的index.html
    • index.html会指明根App组件,如<div id="app">Loading...</div>
    • 若添加JavaScript,则需要添加在</body>之前。
  • _Imports.razor,包含公共Razor条令,例如@using
  • App.razor,根组件,用于设置Router组件
  • Program.cs,app的进入点,用于设置WebAssembly宿主。
    • 通过builder.RootComponents.Add<App>("#app")加到根组件合集,也就是wwwroot/index.html<div id="app">Loading...</div>
    • 服务的添加和配置:例如builder.Services.AddSingleton<IMyDependency, MyDependency>()

Blazor Server

Host and deploy ASP.NET Core Blazor

Publish the app

  • Visual Studio中使用Build > Publish {APPLICATION}
  • .NET CLI中私用dotnet publish -c Release

发布会触发工程依赖的restore操作以及整个工程的构建。没用到的方法和集装体都会被移除。

wasm的发布目录:

  • Standalone:发布在/bin/Release/{TARGET FRAMEWORK}/publish/wwwroot目录。只需将wwwroot中的内容移到宿寄处。
  • Hosted: 发布在服务端应用的/bin/Release/{TARGET FRAMEWORK}/publish/wwwroot目录,需要将publish目录的内容移到宿寄处。

server发布目录

  • /bin/Release/{TARGET FRAMEWORK}/publish,需要将publish目录的内容移到宿寄处。

App base path

app base path是应用的根URL路径,考虑下面的场景:

  • 有一个ASP.NET Core 应用叫做MyApp:
    • 处于d:/MyApp之中
    • 映射的URL是https://www.contoso.com/{MYAPP RESOURCE}
  • 一个Blazor 应用叫做CoolApp,是MyApp的子应用:
    • 处于d:/MyApp/CoolApp
    • 映射的URL是https://www.contoso.com/CoolApp/{COOLAPP RESOURCE}

CoolApp不知道自己的映射URL是/CoolApp/。为了告诉CoolApp,要配置<base>标签的href属性,将其设成相对于wwwroot/index.html或者Pages/_Host.cshtml的路径:

<!-- wwwroot/index.html -->
<base href="/CoolApp/">

<!-- Pages/_Host.cshtml -->
<base href="~/CoolApp/">

base的href属性值的末尾必须带斜线

对于Server应用,还可以通过调用Startup.Configure请求流水线中的UsePathBase来做额外配置:

app.UsePathBase("/CoolApp");

默认宿寄情况下<base href="/" />代表应用的根目录,但是其他宿寄情况下可能要把它设置为服务端为当前应用提供的子URL。

对于运行在非根相对路径下的wasm应用(例如<base href="/CoolApp/">),应用运行时无法从本地找到其物资。需要运行时设置<base>标签的href属性来设置路径:

dotnet run --pathbase=/{RELATIVE URL PATH (no trailing slash)}

注意,不要带末尾斜线

示例,运行于/CoolApp/之下的wasm应用,其设置应该是:

dotnet run --pathbase=/CoolApp

其本地运行URL地址为http://localhost:port/CoolApp

Server应用可以通过设置Startup.Configure中的MapFallbackToPage :

endpoints.MapFallbackToPage("/{RELATIVE PATH}/{**path:nonfile}");

示例,对于https://{HOST}:{PORT}/CoolApp/,其配置:

endpoints.MapFallbackToPage("/CoolApp/{**path:nonfile}");

Host and deploy ASP.NET Core Blazor WebAssembly

有下面部署策略可选:

  • 通过ASP.NET Core应用提供服务
  • 以静态宿寄的方式提供服务

Customize how boot resources are loaded

通过loadBootResource来定制启动时加载的资源。

Compression

wasm应用默认输出的产物是经过压缩的,可以有下面两种压缩方式:

  • Brotli
  • Gzip

禁用压缩要么在MSBuild中设置:

<PropertyGroup>
  <BlazorEnableCompression>false</BlazorEnableCompression>
</PropertyGroup>

要么publish的时候指定:

dotnet publish -p:BlazorEnableCompression=false

Rewrite URLs for correct routing

路由处理在wasm应用中并没有那么直观。

假设有Main.razor和About.razor两个组件。假如根服务在https://www.contoso.com/,当此URL被访问时:

  • 返回默认页面,通常是index.html
  • index.html引导启动应用
  • 加载Blazor的路由,渲染Main组件

假设Main组件有到About组件的链接,点击这个链接是工作的,因为Blazor会阻断浏览器访问About页面,并自行提供About组件的内容。所有到内部端点(endpoint)的请求皆是以此方式工作的,即到内部端点的请求不会转化成浏览器的请求。但若是直接从浏览器地址栏中输入www.contoso.com/About,则会跳过内部处理,从而导致访问失败。

Hosted deployment with ASP.NET Core

略。

Standalone deployment

都是讲具体场景下的配置。

Configure the Trimmer

Change the filename extension of DLL files

讲如果更改应用所发布的.dll文件的名字。

Resolve integrity check failures

blazor.boot.json指定了.dll以及.wasm文件的SHA-256哈希值。

其余略。

Host and deploy Blazor Server

Configure the Trimmer for ASP.NET Core Blazor

Blazor WebAssembly执行IL 剪除以降低生成物尺寸。

剪除可能会过度移除信息,比如将反射相关信息移除。更多参考Trimming options ,下面提供一些常见配置信息:

  • 项目文件中设置<PublishTrimmed>可完全禁止剪除
  • 可以控制剪除的力度
  • 避免对某些集结件的剪除
  • “Root” assemblies for trimming
  • <SuppressTrimAnalysisWarnings设为false时可对剪除反射类型信息提出警告
  • 控制符合剪除以及调试器支持
  • Set Trimmer features for trimming framework library features.

其他参考

(本篇完)

Categories