spa.UseAngularCliServer() 中间件如何为网页提供服务? [英] How does spa.UseAngularCliServer() middleware serve a webpage?

查看:26
本文介绍了spa.UseAngularCliServer() 中间件如何为网页提供服务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 Visual Studio 2017(版本 15.7.2)创建了一个 .Net Core 2.1 Angular 应用程序

I create a .Net Core 2.1 Angular application with Visual Studio 2017 (ver. 15.7.2)

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

I wonder how spa.UseAngularCliServer() serves a page in development mode.

  1. 在调试模式下,虽然网页加载正常,但ClientApp或wwwroot文件夹中没有dist"文件夹.dist文件夹在哪里?

  1. In debug mode, there is no "dist" folder in the ClientApp or wwwroot folder, though the webpage is loaded normally. Where is the dist folder?

看起来 spa 中间件启动了一个 angular-cli 开发服务器,但该网页实际上是由 IIS Express 托管的.ng serve"与 IIS Express 有什么关系?

It looks like that the spa middleware start an angular-cli dev server, but the webpage is actually hosted by IIS Express. How does "ng serve" relate to IIS Express?

表单 starup.cs

Form 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");
                }
            });

推荐答案

虽然这是通过将请求代理到 Angular Development Server 来完成的,但代理不是由 IIS 代理,而是由 ASP.NET Core 代理本身.IIS 不知道 Angular Dev Server 监听的端口.

Although that's done by proxying requests to the Angular Development Server , the proxying is not proxied by IIS , but by ASP.NET Core itself . IIS has no idea about the port listened by Angular Dev Server .

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

npm start -- --port {dynamic_port}

这里的 {dynamic_port} 是在 RunTime 计算的.因为 npm 命令已经在 package.json ,然后它会通过ng serve -- --port {dynamic_port} 启动一个开发服务器.

The {dynamic_port} here is computed at RunTime .Since the npm command has been already configured in package.json , it will then start a dev server byng serve -- --port {dynamic_port} .

  1. 如果 ng serve 运行完美,它会为代理创建一个普通的 HttpClient 并使用它来执行代理(将请求转发到 Angular Dev Servercode> 与普通的 HttpClient ,并将响应复制为它自己的响应).WebSocket 代理将以类似的方式发生.
  1. if the ng serve run flawlessly , it will create a plain HttpClient for proxy and use it to perform proxy (forward requests to Angular Dev Server with the plain HttpClient , and copy the response as it's own response) . The WebSocket proxy will take place in a similar way .

您可以在 GitHub 上找到源代码.易于阅读和理解.

You can find the source code on GitHub . It's easy to read and understand .

在内部,UseAngularCliServer(npmScript: "start") 将调用 AngularCliMiddlewarestep 1step 2 .步骤 1 由 :

Internally , the UseAngularCliServer(npmScript: "start") will invoke AngularCliMiddleware to do step 1 and step 2 . The step 1 is done by :

var angularCliServerInfoTask = StartAngularCliServerAsync(sourcePath, npmScriptName, logger);

StartAngularCliServerAsync 方法会找到一个可用的 TCP 端口,并运行命令 npm start -- --port {port} 启动 ng serve> :

The StartAngularCliServerAsync method will find an available TCP port , and run command npm start -- --port {port} to start 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); 
    // ...
}

#SeeLiddleware6referno完整代码在这里

第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);
    });
}

PerfromProxyRequest() 的实现见此处.对于普通请求,它只是使用普通的 HttpClient 转发它们并将响应复制为自己的响应.

The implementation of PerfromProxyRequest() can be found here . For normal requests , It simply forward them using a plain HttpClient and copy the response as its own response .

回到你的问题:

dist 文件夹在哪里?

Where is the dist folder?

既然你已经配置了一个spa.UseAngularCliServer("start"):

Since you have configured a spa.UseAngularCliServer("start"):

if (env.IsDevelopment())
{
    spa.UseAngularCliServer(npmScript: "start");
}

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

All those requests will be processed by local dev server launched by angular cli. As a result , there's no dist on disk at all . The same will take place if you run the command ng serve manually .

ng serve"与 IIS Express 有什么关系?

How does "ng serve" relate to IIS Express?

IIS 不知道 Angular Dev Server 监听的端口.当有传入消息时,IIS 只是将其发送到您的 ASP.NET Core 服务器.如果静态文件、MVC 或您在 UseSpa() 之前配置的任何其他中间件无法处理请求,ASP.NET Core 会将其转发到开发服务器.

IIS has no idea about the port listened by Angular Dev Server. When there's an incoming message , IIS just sends it to your ASP.NET Core server . If the request cannot be processed by staticFiles , MVC , or any other middlewares that you've configured before UseSpa() , ASP.NET Core will forward it to the Dev Server .

这篇关于spa.UseAngularCliServer() 中间件如何为网页提供服务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆