TL; DR
К сожалению, проблема, похоже, связана с некоторыми изменениями в способе Angular CLI при запуске части angular приложения. В соответствии с этой проблемой:
https://github.com/dotnet/aspnetcore/issues/17277
Предлагаемые решения должны установить прогресс: true в angular. json или выполнить простое эхо до ng подача (https://github.com/dotnet/aspnetcore/issues/17277#issuecomment -562433864 ).
Полный ответ
Я выкопал asp. net базовый код базы (https://github.com/dotnet/aspnetcore), посмотрим, как шаблон Angular запускает приложение Angular.
Основной механизм, запускающий сервер angular, представлен двумя классами: AngularCliMiddleware (https://git.io/JvlaL ) и NodeScriptRunner (https://git.io/Jvlaq).
В AngularCliMiddleware мы находим этот код (я удалил исходные комментарии и добавил некоторые свои собственные, чтобы объяснить несколько вещей):
public static void Attach(ISpaBuilder spaBuilder, string npmScriptName)
{
var sourcePath = spaBuilder.Options.SourcePath;
if (string.IsNullOrEmpty(sourcePath))
{
throw new ArgumentException("Cannot be null or empty", nameof(sourcePath));
}
if (string.IsNullOrEmpty(npmScriptName))
{
throw new ArgumentException("Cannot be null or empty", nameof(npmScriptName));
}
// Start Angular CLI and attach to middleware pipeline
var appBuilder = spaBuilder.ApplicationBuilder;
var logger = LoggerFinder.GetOrCreateLogger(appBuilder, LogCategoryName);
var angularCliServerInfoTask = StartAngularCliServerAsync(sourcePath, npmScriptName, logger);
var targetUriTask = angularCliServerInfoTask.ContinueWith(
task => new UriBuilder("http", "localhost", task.Result.Port).Uri);
SpaProxyingExtensions.UseProxyToSpaDevelopmentServer(spaBuilder, () =>
{
var timeout = spaBuilder.Options.StartupTimeout;
return targetUriTask.WithTimeout(timeout,
$"The Angular CLI process did not start listening for requests " +
// === NOTE THIS LINE, THAT CARRIES THE "0 seconds" BUG!!!
$"within the timeout period of {timeout.Seconds} seconds. " +
$"Check the log output for error information.");
});
}
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);
npmScriptRunner.AttachToLogger(logger);
Match openBrowserLine;
using (var stdErrReader = new EventedStreamStringReader(npmScriptRunner.StdErr))
{
try
{
// THIS LINE: awaits for the angular server to output
// the 'open your browser...' string to stdout stream
openBrowserLine = await npmScriptRunner.StdOut.WaitForMatch(
new Regex("open your browser on (http\\S+)", RegexOptions.None, RegexMatchTimeout));
}
catch (EndOfStreamException ex)
{
throw new InvalidOperationException(
$"The NPM script '{npmScriptName}' exited without indicating that the " +
$"Angular CLI was listening for requests. The error output was: " +
$"{stdErrReader.ReadAsString()}", ex);
}
}
var uri = new Uri(openBrowserLine.Groups[1].Value);
var serverInfo = new AngularCliServerInfo { Port = uri.Port };
await WaitForAngularCliServerToAcceptRequests(uri);
return serverInfo;
}
Как видите, метод StartAngularCliServerAsyn c создает новый объект NpmScriptRunner , который является оболочкой для вызова метода Process.Start, в основном, присоединяет регистратор и затем ожидает, когда StdOut процесса испустит что-то, что соответствует «откройте ваши брови» на httpSOMETHING ... ".
Забавно, что это должно работать !
Если вы запускаете ng serve (или npm run start) в папке ClientApp, как только сервер запускается, он все еще выдает вывод «откройте ваш браузер на http ...».
Если вы запускаете приложение tnet, сервер узла фактически запускается, просто включите все журналы в режиме отладки. найдите строку «Starting @ angular / cli on port ...» и попробуйте посетить localhost на этом порту, и вы увидите, что ваше angular приложение работает.
Проблема в том, что по какой-то причине StdOut больше не получает строку «открыть ваш браузер» и не записывается регистратором ... кажется, что каким-то образом эта конкретная строка вывода из ng serve задерживается, как будто она больше не отправляется в выводе Stardard поток. Метод WaitForMatch достигает своего тайм-аута через 5 секунд и отлавливается из кода метода расширения WithTimeout, который выводит (ошибочное) сообщение «... 0 секунд ...».
Что я мог видеть После запуска tnet приложения запускается последовательность процессов, но я не заметил разницы в командной строке от Angular 8 до Angular 9.
My Теория заключается в том, что в CLI Angular что-то было изменено, что препятствует отправке этой строки в stdout, поэтому прокси. net не перехватывает его и не может определить, когда запущен сервер angular.
Согласно этой проблеме:
https://github.com/dotnet/aspnetcore/issues/17277
Предлагаемые решения должны установить прогресс: true в angular. json или выполнить простое эхо до подачи нг (https://github.com/dotnet/aspnetcore/issues/17277#issuecomment -562433864 ).