spa.UseAngularCliServer()中间件如何服务网页?

3 .net-core asp.net-core angular-cli angular

我使用Visual Studio 2017(版本15.7.2)创建了.Net Core 2.1 Angular应用程序 在此处输入图片说明

我想知道spa.UseAngularCliServer()如何在开发模式下提供页面。

  1. 在调试模式下,尽管网页已正常加载,但ClientApp或wwwroot文件夹中没有“ dist”文件夹。dist文件夹在哪里?

  2. 看来,spa中间件启动了angular-cli dev服务器,但该网页实际上是由IIS Express托管的。“ ng服务”与IIS Express有何关系?

形成starup.cs

app.UseSpa(spa =>
            {
                // To learn more about options for serving an Angular SPA from ASP.NET Core,
                // see https://go.microsoft.com/fwlink/?linkid=864501

                spa.Options.SourcePath = "ClientApp";

                if (env.IsDevelopment())
                {
                    spa.UseAngularCliServer(npmScript: "start");
                }
            });
Run Code Online (Sandbox Code Playgroud)

itm*_*nus 9

尽管这是通过将请求代理到来完成的Angular Development Server,但代理不是由IIS代理,而是由ASP.NET Core本身代理。IIS不了解Angular Dev Server侦听的端口

  1. UseAngularCliServer("start") 首先会调用命令

    npm start -- --port {dynamic_port}
    
    Run Code Online (Sandbox Code Playgroud)

{dynamic_port}这里计算的RunTime。自从npm命令已经被配置在package.json,它就会启动一个开发服务器ng serve -- --port {dynamic_port}

  1. 如果ng serve运行正常,它将HttpClient为代理创建一个纯文本并使用它执行代理(将请求转发到Angular Dev ServerHttpClient文本,并将响应复制为自己的响应)。该WebSocket代理将在一个类似的方式。

您可以在GitHub上找到源代码。很容易阅读和理解。

在内部,UseAngularCliServer(npmScript: "start")意志会调用AngularCliMiddlewarestep 1step 2。步骤1通过以下方式完成:

var angularCliServerInfoTask = StartAngularCliServerAsync(sourcePath, npmScriptName, logger);
Run Code Online (Sandbox Code Playgroud)

StartAngularCliServerAsync方法将找到可用的TCP端口,并运行命令npm start -- --port {port}以启动ng serve

private static async Task<AngularCliServerInfo> StartAngularCliServerAsync(
    string sourcePath, string npmScriptName, ILogger logger)
{
    var portNumber = TcpPortFinder.FindAvailablePort();
    logger.LogInformation($"Starting @angular/cli on port {portNumber}...");
    var npmScriptRunner = new NpmScriptRunner( sourcePath, npmScriptName, $"--port {portNumber}", null); 
    // ...
}
Run Code Online (Sandbox Code Playgroud)

在这里查看完整的代码

步骤2通过以下步骤完成:

public static void UseProxyToSpaDevelopmentServer(this ISpaBuilder spaBuilder, Func<Task<Uri>> baseUriTaskFactory)
{
    // ...
    // Proxy all requests to the SPA development server
    applicationBuilder.Use(async (context, next) =>
    {
        var didProxyRequest = await SpaProxy.PerformProxyRequest( context, neverTimeOutHttpClient, baseUriTaskFactory(), applicationStoppingToken, proxy404s: true);
    });
}
Run Code Online (Sandbox Code Playgroud)

的实现PerfromProxyRequest()可以在这里找到。对于正常的请求,它只是简单地将其转发,HttpClient然后将响应复制为自己的响应。

回到您的问题:

dist文件夹在哪里?

由于您已经配置了spa.UseAngularCliServer("start")

if (env.IsDevelopment())
{
    spa.UseAngularCliServer(npmScript: "start");
}
Run Code Online (Sandbox Code Playgroud)

所有这些请求将由angular cli启动的本地开发服务器处理。结果,dist磁盘上根本没有磁盘。如果您ng serve手动运行命令,将会发生同样的情况。

“ ng服务”与IIS Express有何关系?

IIS不了解Angular Dev Server侦听的端口。当收到传入消息时,IIS会将其发送到您的ASP.NET Core服务器。如果该请求不能由staticFiles,MVC或您之前配置的任何其他中间件处理UseSpa(),则ASP.NET Core会将其转发到Dev Server。