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 .
UseAngularCliServer("start") will firstly invoke the command
npm start -- --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} .
- 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 .
You can find the source code on GitHub . It's easy to read and understand .
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);
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);
// ...
}
See the complete code here
And the Step 2 is done by :
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);
});
}
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 .
Back to your question :
Where is the dist folder?
Since you have configured a spa.UseAngularCliServer("start"):
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
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 .
How does "ng serve" relate to IIS Express?
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 .