38

升级到 Angular 9 后出现此错误。我正在使用 Visual Studio 2019、带有 Angular 的 ASP .NET 核心。即使我创建新项目并将 angular 更新到 9 版本,它也会停止工作。

页面响应的完整列表是:

TimeoutException:Angular CLI 进程未在 0 秒的超时时间内开始侦听请求。检查日志输出以获取错误信息。Microsoft.AspNetCore.SpaServices.Extensions.Util.TaskTimeoutExtensions.WithTimeout(任务任务,TimeSpan timeoutDelay,字符串消息) Microsoft.AspNetCore.SpaServices.Extensions.Proxy.SpaProxy.PerformProxyRequest(HttpContext 上下文,HttpClient httpClient,任务 baseUriTask,CancellationToken applicationStoppingToken,bool proxy404s) Microsoft.AspNetCore.Builder.SpaProxyingExtensions+<>c__DisplayClass2_0+<b__0>d.MoveNext() Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext 上下文)

我的 package.json 是:

{
  "name": "webapplication10",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "build:ssr": "ng run WebApplication10:server:dev",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "9.0.0",
    "@angular/cdk": "~9.0.0",
    "@angular/common": "9.0.0",
    "@angular/compiler": "9.0.0",
    "@angular/core": "9.0.0",
    "@angular/forms": "9.0.0",
    "@angular/material": "~9.0.0",
    "@angular/platform-browser": "9.0.0",
    "@angular/platform-browser-dynamic": "9.0.0",
    "@angular/platform-server": "9.0.0",
    "@angular/router": "9.0.0",
    "@nguniversal/module-map-ngfactory-loader": "8.1.1",
    "aspnet-prerendering": "^3.0.1",
    "bootstrap": "^4.4.1",
    "core-js": "^3.6.4",
    "jquery": "3.4.1",
    "oidc-client": "^1.10.1",
    "popper.js": "^1.16.1",
    "rxjs": "^6.5.4",
    "tslib": "^1.10.0",
    "zone.js": "~0.10.2"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^0.900.1",
    "@angular/cli": "9.0.1",
    "@angular/compiler-cli": "9.0.0",
    "@angular/language-service": "9.0.0",
    "@types/jasmine": "^3.5.3",
    "@types/jasminewd2": "~2.0.8",
    "@types/node": "^12.12.27",
    "codelyzer": "^5.2.1",
    "jasmine-core": "~3.5.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "^4.4.1",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage-istanbul-reporter": "^2.1.1",
    "karma-jasmine": "~3.1.1",
    "karma-jasmine-html-reporter": "^1.5.2",
    "typescript": "3.7.5"
  },
  "optionalDependencies": {
    "node-sass": "^4.12.0",
    "protractor": "~5.4.2",
    "ts-node": "~8.4.1",
    "tslint": "~5.20.0"
  }
}
```
4

19 回答 19

43

TL;博士

遗憾的是,这个问题似乎与 Angular CLI 启动应用程序的角度部分的方式发生了一些变化。根据这个问题:

https://github.com/dotnet/aspnetcore/issues/17277

建议的解决方案是在 angular.json 中设置进度:true 或在 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;
}

如您所见,StartAngularCliServerAsync方法创建了一个新的NpmScriptRunner对象,它是 Process.Start 方法调用的包装器,基本上,附加记录器,然后等待进程的 StdOut 发出与“打开浏览器”匹配的内容http有些东西……”。

有趣的是这应该工作

如果您在 ClientApp 文件夹中运行 ng serve(或 npm run start),一旦服务器启动,它仍然会发出输出“在 http 上打开您的浏览器...”。

如果你 dotnet 运行应用程序,节点服务器实际上会启动,只需在 Debug 模式下启用所有日志,找到“Starting @angular/cli on port ...”行并尝试在该端口上访问 localhost,你会看到您的 Angular 应用程序正在运行。

问题是,由于某种原因,StdOut 不再获得“打开您的浏览器”行,也不是由记录器编写的......似乎以某种方式阻止了来自 ng serve 的特定输出行,就像它一样不再在标准输出流中发送。WaitForMatch 方法在 5 秒后超时,并从 WithTimeout 扩展方法的代码中捕获,该方法输出(错误)“... 0 seconds ...”消息。

就我所见,一旦你 dotnet 运行你的应用程序,就会依次产生一系列进程,但我没有注意到从 Angular 8 到 Angular 9 的命令行有任何区别。

我的理论是 Angular CLI 中的某些内容已更改,阻止该行在标准输出中发送,因此 .net 代理无法捕获它并且无法检测角度服务器何时启动。

根据这个问题:

https://github.com/dotnet/aspnetcore/issues/17277

建议的解决方案是在 angular.json 中设置进度:true 或在 ng 服务之前执行简单的回显(https://github.com/dotnet/aspnetcore/issues/17277#issuecomment-562433864)。

于 2020-02-14T21:37:25.593 回答
32

我通过更改解决了它:

"scripts": {   
        "start": "ng serve",

到:

 "scripts": {   
        "start": "echo Starting... && ng serve",

package.json

于 2020-05-29T14:10:43.893 回答
10

这是我所做的

来自 Fairlie Agile,在 main.ts 中注释掉了这一行

export { renderModule, renderModuleFactory } from '@angular/platform-server';

来自 Claudio Valerio 在 angular.json 中,设置

"progress": true,

现在我可以通过单击 F5 / Run IIS Express 来运行该应用程序

于 2020-02-25T23:07:19.350 回答
8

正如https://developercommunity.visualstudio.com/solutions/446713/view.html中所建议的,您应该设置 StartupTimeout 配置设置。

基本上在 Startup.cs 中:

 app.UseSpa(spa =>
    {
      spa.Options.SourcePath = "./";
      //Configure the timeout to 5 minutes to avoid "The Angular CLI process did not start listening for requests within the timeout period of 50 seconds." issue
      spa.Options.StartupTimeout = new TimeSpan(0, 5, 0);
      if (env.IsDevelopment())
      {
        spa.UseAngularCliServer(npmScript: "start");
      }
    });
于 2020-02-12T14:08:30.417 回答
7

这是一种解决方法:

  • 在 package.json 中将启动脚本从“ng serve”更改为“ngserve”
"scripts": {
  "start": "ngserve",
  • 在同一目录中创建一个文件 ngserve.cmd,其内容如下:
@echo ** Angular Live Development Server is listening on localhost:%~2, open your browser on http://localhost:%~2/ **
ng serve %1 %~2

现在,Dotnet 得到了它正在等待的线路。之后命令 ng serve 将启动服务器(所以实际上 Angular Live Development Server 还没有监听),浏览器将打开,首先它不会工作(ng serve 仍在编译),但如果你按下 reload 之后一会儿,应该就好了。

这只是一种解决方法,但它对我们有用。

于 2020-04-27T08:01:01.687 回答
7

package.json像这样在文件中为服务过程添加了详细信息。

"scripts": {
  "ng": "ng",
  "start": "ng serve --verbose",
  "build": "ng build", ...
}, ...

不知道它为什么起作用,但我觉得它在某种程度上与引起与 echo 相同的减速有关。

于 2020-06-28T21:43:04.953 回答
5

要解决严格模式错误,请从 main.ts 中删除此行

export { renderModule, renderModuleFactory } from '@angular/platform-server';

但是,这并不能解决超时问题。升级到 Angular 9 并使用 .NET 核心后,我也收到此错误。

使用“ng serve”运行 Angular 应用程序,然后将启动 spa 脚本更改为使用 UseProxyToSpaDevelopmentServer 作为解决方法

于 2020-02-14T02:58:18.730 回答
5

我在启动类的配置方法中更改了使用 spa 管道配置,它对我有用。

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.StartupTimeout = new System.TimeSpan(0, 15, 0);
                spa.Options.SourcePath = "ClientApp";

                if (env.IsDevelopment())
                {
                    spa.UseAngularCliServer(npmScript: "start");
                }
            });
于 2021-02-12T08:49:31.137 回答
4

如果您只做后端工作,请在您的 startup.cs 中注释掉

spa.UseAngularCliServer(npmScript: "start");

并添加

spa.UseProxyToSpaDevelopmentServer("http://localhost:4200");

像这样...

//spa.UseAngularCliServer(npmScript: "start");
spa.UseProxyToSpaDevelopmentServer("http://localhost:4200");//Todo Switch back for SPA Dev

通过 npm start 从 cmd(在 ClientApp 目录中)运行 SPA。

然后,当您从 Visual Studio 运行或调试完整的应用程序时,它会运行得更快。

于 2020-10-20T06:55:14.540 回答
3

在 package.json 中将 ng serve 更改为 ng serve --host 0.0.0.0 在此处输入图像描述

于 2020-05-01T16:31:55.437 回答
1

在我的情况下,SpaServices 或 ts-node 没有捕获到 TypeScript 编译错误。存在使用具有不同名称空间的相同文件名的引用,这使运行时编译器感到困惑。在 ClientApp 文件夹中执行 ng build 并确保没有错误。

于 2020-09-14T18:16:01.500 回答
1

这里没有一个解决方案对我有用。在我将解决方案的组件升级到最新版本后,问题就开始了。唯一对我有用的是将我的全局角度 cli 升级到与本地版本相同的版本:

npm uninstall -g angular-cli
npm cache clean
npm cache verify
npm install -g @angular/cli@latest
于 2020-10-26T13:19:47.220 回答
1

更改为 .NET5 解决了我的问题。你也可以试试这个:

 "scripts": {   
    "start": "echo start && ng serve",

或者

"start": "ng serve --port 0000",

在 package.json

于 2021-04-26T07:05:27.417 回答
0

出于开发目的,如果您收到错误为“TimeoutException:Angular CLI 进程未在 0 秒的超时期限内开始侦听请求。” .

请遵循这两个对我也有用的步骤:

在命令提示符下,运行“ng serve”命令以运行角度解决方案。在 startup.cs 文件中,将启动超时更改为分钟。即使它不会花费太多时间,因为角度解决方案已经在运行。-> spa.Options.StartupTimeout = new TimeSpan(0, 5, 0);

如果对你有帮助请标记答案!!

谢谢。

于 2021-02-12T07:59:44.630 回答
0

npm install -g @angular/cli从命令提示符运行

于 2021-03-25T12:04:57.513 回答
0
"scripts": {
    "ng": "ng",
    "start": **"ng serve --port 33719 --open",**
    "build": "ng build",

使用 package.json 中以粗体显示的设置

于 2021-04-24T04:51:32.540 回答
0

我遇到了类似的问题,我在 package.json 文件中进行了以下更新

"scripts": {
    "ng": "ng",
    "start": "echo hello && ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
}

请参阅 [dotnet/angular - issues/17277] 中的 github 分辨率

于 2021-06-17T11:45:03.447 回答
0

我做了所有这些成功的建议。但是超时问题仍然存在。就我而言,以下内容对我有用,(将附上所有步骤)

  1. 注释以下行main.ts以解决strict mode问题

    export { renderModule, renderModuleFactory } from '@angular/platform-server';

  2. 在文件中更改ng serveecho Starting && ng servepackage.json

  3. 只需ng serve使用 Node.js 命令提示符手动运行命令。然后尝试在 Visual Studio 中运行该项目。

于 2021-11-30T23:44:57.943 回答
-1

最好的方法是在启动时插入这一行

spa.UseProxyToSpaDevelopmentServer("http://localhost:4200");

然后从 Visual Studio 运行或调试您的应用程序。

于 2021-01-10T19:03:21.907 回答