Skip to content

.NET Core 3.0 + Angular 9 cli application called via the SpaServices extensions hangs in common configuration #17277

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
miguellira opened this issue Nov 20, 2019 · 77 comments
Labels
affected-most This issue impacts most of the customers area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates bug This issue describes a behavior which is not expected - a bug. feature-spa investigate severity-major This label is used by an internal tool
Milestone

Comments

@miguellira
Copy link

miguellira commented Nov 20, 2019

Describe the bug

Running a .NET Core 3.0 + Angular 9 cli (version 9.0.0-rc.2 as of this post) with the angular cli build option progress set to false will hang until the StartupTimeout expires (default: 120 seconds)

To Reproduce

I created a repo with a bare bones .NET Core 3.0 + Angular 9 cli application to demo the bug. Simply clone, npm build the ClientApp folder, and dotnet run. Or you can follow the steps below to do this from scratch:

  1. Ensure you have .NET Core 3.0 installed
  2. Create a .NET Core application with the current Angular templates by typing: dotnet new angular -n HelloWorld
  3. Navigate to the ClientApp folder and install the Typescript helper functions required for Angular 9 by typing: npm install tslib@latest
  4. Update to Angular 9 by typing: ng update @angular/core @angular/cli --next
  5. Ensure the progress build option in the angular.json file is set to false
  6. Run the application by navigating back to the root folder and typing: dotnet run
  7. Launch a browser and navigate to: https://localhost:5001

The application will hang and eventually timeout.

Further technical details

This appears to be caused by a change in how ng serve outputs to the console in the new Angular 9 CLI. The AngularCliMiddleware makes a WaitForMatch() method call against the standard output to signify when the Angular assets have been generated and the web server is ready to receive requests (Line 84). However, unless the progress option is set to true in the angular.json file you never see the expected line.

UPDATE: Updated to .NET Core 3.1 and Angular 9.0.0-rc.5. Same issue. New, simpler workaround is to modify your npm start script to perform a simple echo prior to ng serve (see comment below)

UPDATE (6/5/2020): Lots of recent comments so I figured I'd share exactly what has worked for me with every release of .NET and Angular since my original post. Update your package.json like so:

  "scripts": {
    "ng": "ng",
    "start": "echo hello && ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  }
@Pilchie Pilchie added the area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates label Nov 21, 2019
@mkArtakMSFT mkArtakMSFT added this to the 5.0.0-preview1 milestone Nov 21, 2019
@benelliott
Copy link

I also have this issue, but don't want to have to re-enable progress as webpack's build progress output is routed to stderr, and this makes log4net go a bit nuts. If this could be solved in a different way it would be great - especially since listening for the dev server to spit out a specific string always felt a bit fragile.

@benelliott
Copy link

benelliott commented Nov 25, 2019

Actually, I don't think it's quite as simple as that - when I run ng serve --progress=false from my App directory, I still see the listening on... message.

I think the problem is that the message will only show on the first log output from the CLI (https://github.com/angular/angular-cli/blob/2c0efd834b08ac5ea166d88c0ff57cc35df19421/packages/angular_devkit/build_angular/src/dev-server/index.ts#L361) and this often takes longer than the five second default timeout after which .NET assumes that the CLI has died (https://github.com/aspnet/AspNetCore/blob/master/src/Middleware/SpaServices.Extensions/src/AngularCli/AngularCliMiddleware.cs#L22).

@elianora
Copy link

elianora commented Dec 5, 2019

I am using .NET Core 3.1 and am encountering the same issue using @angular/cli@~9.0.0-rc.5. I never get the line expected by the AngularCliMiddleware from the Angular CLI. I have had it work correctly intermittently with both --progress=true and --progress=false.

I have zero clue as to why the following workaround works, but I consistently get the expected behavior if I add any statement that outputs to stdout prior to ng serve . My package.json script is echo hello && npm serve --progress=false, and I get the following reliably:

image

EDIT: Adding environment info:

  • Windows 10 build 18363
  • Node.js 12.13.0
  • Visual Studio Code 1.40.2
  • dotnet CLI 3.1.100
  • @angular/cli 9.0.0-rc.5

@benelliott
Copy link

benelliott commented Dec 5, 2019

@elianora I spent some time digging around today and found this bug: #6146

Basically, the wrapper around StdOut might miss the listening on... message if it's at the end of a block with lots of newlines. As of Angular 9 this is a problem because the message is more likely to be printed in the same block as the webpack chunk output.

Could you check that you're referencing the latest version of the SpaServices packages? I think this fix (ab02951) is only present in 3.0.0 onwards.

@elianora
Copy link

elianora commented Dec 5, 2019

I am currently referencing 3.1.0 and my TargetFramework is set to netcoreapp3.1.

@benelliott
Copy link

I've made a shamelessly hacky workaround which will do for now. Basically, I wrap the call to the Angular CLI in another Node script, and spoof the "open your browser on" message so that dotnet notices it.

You can try the workaround yourself:

  1. Edit your package.json to rename your start script to start:ng
  2. Add a new start script: "start": "node start-dotnet.js". Your package.json should look like
        "start":  "node start-for-dotnet.js",
        "start:ng": "ng serve [or whatever you had before]",
  1. Next to your package.json, add a file called start-dotnet.js with contents
// Hack to work around https://github.com/aspnet/AspNetCore/issues/17277

const { spawn } = require('child_process');

const portArgIndex = process.argv.indexOf('--port');

if (portArgIndex === -1) {
    throw new Error('Could not detect port number');
}

const port = process.argv[portArgIndex + 1];

console.log(`open your browser on http://localhost:${port}`);

const child = spawn(`cmd`, ['/c', `npm.cmd run start:ng -- --port ${port}`]);

console.log('Angular CLI started on PID', child.pid);

child.stdout.on('data', x => console.log(x && x.toString()));

child.stderr.on('data', x => console.error(x && x.toString()));

const sleep = () => {
    console.log('[Node.js keepalive]');
    setTimeout(sleep, 10000);
}

sleep();

@benelliott
Copy link

const child = spawn(`cmd`, ['/c', `npm.cmd run start:ng -- --port ${port}`]);

This line is Windows-specific, the Linux equivalent would be something along the lines of (but possibly not exactly)

const child = spawn(`npm`, ['run', `start:ng -- --port ${port}`]);

@elianora
Copy link

elianora commented Dec 5, 2019

I run into no issues just using echo something && ng serve, but certainly will keep this in mind if I or anyone else I'm working with run into this issue again; when I get home I will see what the behavior on other operating systems looks like.

@benelliott
Copy link

Do you still have dotnet randomly choosing a CLI port when you do that?

@elianora
Copy link

elianora commented Dec 5, 2019

I do, yes.

@miguellira
Copy link
Author

@elianora suggestion of modifying the npm start script in your package.json by adding an echo statement prior to ng serve is enough to notify the AngularCliMiddleware the angular dev server is running. This is a better workaround than setting the progress flag to true.

BTW, can't see how it would matter but I did notice a subtle difference in how the Angular CLI outputs build info between Angular 8 and 9. Specifically, the Date and Hash information comes after the chunk information in Angular 9, where as it is the first line in Angular 8.


info: Microsoft.AspNetCore.SpaServices[0]
chunk {main} main.js, main.js.map (main) 60.7 kB [initial] [rendered]
chunk {polyfills} polyfills.js, polyfills.js.map (polyfills) 140 kB [initial] [rendered]
chunk {runtime} runtime.js, runtime.js.map (runtime) 6.15 kB [entry] [rendered]
chunk {styles} styles.js, styles.js.map (styles) 9.94 kB [initial] [rendered]
chunk {vendor} vendor.js, vendor.js.map (vendor) 2.99 MB [initial] [rendered]
Date: 2019-12-06T04:20:45.321Z - Hash: 6ee5d8996273b040afe7 - Time: 5917ms <-- This is now on one line and in a new location in Angular 9
...

Of course the actual string the AngularCliMiddleware is searching for: "open your browser on" is still being emitted by the angular_devkit package (Line 303).

@benelliott
Copy link

benelliott commented Dec 6, 2019

The echo workaround works for me too... so my workaround might be slight overkill :)

I don't fully get why it fixes it though...

EDIT: it seems that when I add the --aot flag, the echo workaround no longer helps. I have to use the NodeJS workaround in this case.

@krisztiankocsis
Copy link

krisztiankocsis commented Jan 12, 2020

ng serve --verbose also helps!

@krisztiankocsis
Copy link

But as verbose mode extremely pollutes the console, it would be better to detect readiness by a background HTTP GET instead of parsing the console output.

@pbarranis
Copy link

pbarranis commented Feb 14, 2020

Due to a dependency, I'm unable to upgrade my .NET Core 2.2 app to 3 yet, so when I upgraded to Angular 9 I ran into this issue as well. The echo solution saved me; thank you @elianora !

Side note: I don't have progress set to false. It is true and I still ran into this issue, so I don't know that that's a factor here.

@blogcraft
Copy link

Echo solution works sometimes. Some other times, it just hangs after logging the chunks without printing this message:

info: Microsoft.AspNetCore.SpaServices[0] : Compiled successfully.

@JessyParis
Copy link

I encounter the same issue, and the "echo" workaround works for me (even if I don't understand why).
I don't know if it may help but
with Angular 8 I had this lines

Microsoft.AspNetCore.SpaServices: Information: i ´¢ówds´¢ú: webpack output is served from /
i ´¢ówds´¢ú: 404s will fallback to //index.html

Microsoft.AspNetCore.SpaServices: Information: chunk {main} main.js, main.js.map (main) 1.29 MB [initial] [rendered]
chunk {polyfills} polyfills.js, polyfills.js.map (polyfills) 284 kB [initial] [rendered]
chunk {runtime} runtime.js, runtime.js.map (runtime) 6.15 kB [entry] [rendered]
chunk {styles} styles.css, styles.css.map (styles) 827 kB [initial] [rendered]
chunk {vendor} vendor.js, vendor.js.map (vendor) 10.8 MB [initial] [rendered]
Date: 2020-02-20T14:29:22.992Z - Hash: 6706dd23fbf91f7a606a - Time: 20082ms

Microsoft.AspNetCore.SpaServices: Information: ** Angular Live Development Server is listening on localhost:50733, open your browser on http://localhost:50733/ **
i ´¢ówdm´¢ú: Compiled successfully.

With Angular 9: the line 404s will fallback to //index.html is not there anymore

Microsoft.AspNetCore.SpaServices: Information: > [email protected] start D:\Sources\Repos\Valorplast\eValorplastWebApp\ClientApp
> ng serve "--port" "51738"

Microsoft.AspNetCore.SpaServices: Information: chunk {main} main.js, main.js.map (main) 2.15 MB [initial] [rendered]
chunk {polyfills} polyfills.js, polyfills.js.map (polyfills) 140 kB [initial] [rendered]
chunk {runtime} runtime.js, runtime.js.map (runtime) 6.15 kB [entry] [rendered]
chunk {styles} styles.css, styles.css.map (styles) 889 kB [initial] [rendered]
chunk {vendor} vendor.js, vendor.js.map (vendor) 12.6 MB [initial] [rendered]
Date: 2020-02-20T14:57:58.254Z - Hash: 081b4ea7fae540c9d19b - Time: 25137ms

Microsoft.AspNetCore.SpaServices: Information: ** Angular Live Development Server is listening on localhost:51738, open your browser on http://localhost:51738/ **
: Compiled successfully.

@kurtisauc3
Copy link

Still waiting on a fix for this. The echo solution doesn't work for me, but the node does. It's pretty ugly. Not sure if angular needs to change the way they emit to the console or the spa service extension needs to change the way it listens.

For anyone wanting to use Angular 9 with a netcore3 app, i would recommend going back to angular 8 until this gets resolved. Otherwise the node hack from @benelliott worked for me

@hordani
Copy link

hordani commented Mar 4, 2020

What worked for me was changing "ng serve" to "ng serve --host 0.0.0.0" in package.json "start"

@zql9000
Copy link

zql9000 commented Mar 9, 2020

Hello, I had the same problem and I performed several tests on different projects and simply saving some change in a file inside the ClientApp folder, it makes angular recompile and then VS2019 / VSCode recognizes the node server, without changing any configuration. I comment this in case it helps anyone.

I also tested in the solution of the repo miguellira/Angular9CliTemplateBug with VS 2019 Community and VS Code and works.

@ravimsnetdev
Copy link

What worked for me was changing "ng serve" to "ng serve --host 0.0.0.0" in package.json "start"

this worked for me

@markoj21
Copy link

markoj21 commented Mar 9, 2020

The above solutions did not work for me but this did

  1. In your Startup class, replace the spa.UseAngularCliServer invocation with the following:
    spa.UseProxyToSpaDevelopmentServer("http://localhost:4200");
  2. In a command prompt, switch to the ClientApp subdirectory, and launch the Angular CLI development server:
    cd ClientApp
    npm start
  3. Run the solution like normal

@miguellira
Copy link
Author

Every few days both new and senior .NET developers stumble upon this bug and post a comment to share their frustration. Although I can sympathize, as the OP it surprises me since I thought I did a decent job describing various workarounds including the simplest one that has worked for me with every release of .NET or Angular since my original post:

update the scripts section in package.json by adding an echo statement prior to ng serve

Lately, however, some of the posts have expressed concerns of back porting the "fix" to .NET 3.x so I wanted to share my thoughts:

  1. It can be argued that updating the dotnet templates to include the echo statement by default is harmless enough, however, that would mask the underlying issue which I guess is why that simple change hasn't been done.

  2. More importantly, this bug only surfaces during the development of a .NET application using the SpaServices extensions since that is when you would proxy requests to a local instance of your Angular app served up via ng serve. When you actually publish your .NET application, your Angular app gets compiled and those artifacts are published to a dist folder which the SpaServices extensions will serve as static files. The Angular CLI at this point is no longer in the picture.

Hope that clears up the back porting concern.

I will also update the original post to better describe the simplest workaround.

@ghost
Copy link

ghost commented Jun 20, 2020

i am getting this error

angular/angular#34970

is the error related to this issue?
should i just remove below from main.ts? what are the implication if i do this?

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

or should i just keep using angular 8?

@kemmis
Copy link

kemmis commented Aug 25, 2020

@hoksource you can just remove that line. that issue is not related to this one. when the angular cli upgrades your app to v9 it dumps that line into main.ts in a subjectively dumb way. it's helpful to have it there for those using universal (if i remember correctly), but it's problematic for those of us not using universal.

@kemmis
Copy link

kemmis commented Aug 28, 2020

FWIW, I was able to fix this in my project by forking my own copy of the Microsoft.AspNetCore.SpaServices.Extensions project (from the 2.1 release branch), and then dropping in the internal EventedStreamReader class from the .net 5 release branch. This seems to solve the problem where it never sees the line saying "open your browser...".

@blogcraft
Copy link

Looks that aspnet team no longer cares about the Angular template... net5 still installs angular 8 even tho angular 11 is almost out.

@mkArtakMSFT mkArtakMSFT added affected-most This issue impacts most of the customers severity-major This label is used by an internal tool labels Oct 8, 2020 — with ASP.NET Core Issue Ranking
@javiercn javiercn added the bug This issue describes a behavior which is not expected - a bug. label Oct 9, 2020
@ghost
Copy link

ghost commented Oct 9, 2020

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

@paulcsiki
Copy link

This also affected me but the workaround worked with .NET Core 3.1 and Angular 10.1.

@pbarranis
Copy link

pbarranis commented Dec 15, 2020

I recently upgraded from Angular 10.1.1 to 10.2.3, and this problem inexplicably got a lot more frequent, to the point of being unusable. This is with the echo and progress solutions in place. So I tried upgraded my Microsoft.AspNetCore.* NuGet packages to 3.1.10, and I also tried upgrading Angular to 11.0.4. With those upgrades done, I am unable to get any solution mentioned above to work aside from "Run "ng serve" independently" from the Docs.

That is to say, for me, this problem now has no known solution other than completely abandoning the automatic background Ng CLI process, as it is now non-functional 100% of the time. I can't explain why or who it suddenly broke except for the upgrade from Angular 10.1.1 to 10.2.3.

It's unthinkable to me that a problem this bad has been ignored by MSFT for over a year now.

@blogcraft
Copy link

I recently upgraded from Angular 10.1.1 to 10.2.3, and this problem inexplicably got a lot more frequent, to the point of being unusable. This is with the echo and progress solutions in place. So I tried upgraded my Microsoft.AspNetCore.* NuGet packages to 3.1.10, and I also tried upgrading Angular to 11.0.4. With those upgrades done, I am unable to get any solution mentioned above to work aside from "Run "ng serve" independently" from the Docs.

That is to say, for me, this problem now has no known solution other than completely abandoning the automatic background Ng CLI process, as it is now non-functional 100% of the time. I can't explain why or who it suddenly broke except for the upgrade from Angular 10.1.1 to 10.2.3.

It's unthinkable to me that a problem this bad has been ignored by MSFT for over a year now.

I upgraded to .Net 5 and it got way better. With 3.1 it was unusable.

@mrjohnr
Copy link

mrjohnr commented Dec 31, 2020

I have this bug only on debugging (F5) on .NET 3.1+Angular 11.0.5.only work after I try for 9 or 10 times,too hard to debug...
tried all fixes but none works

@dmsch
Copy link

dmsch commented Jan 15, 2021

The only workaround that worked for us (.NET 3.1.11 + Angular 11.0.5):
angular/angular-cli#16961 (comment)

@heart2friend
Copy link

heart2friend commented Apr 9, 2021

Giving timeout exception for .Net 5.0 and angular 11.0.4

TimeoutException: The Angular CLI process did not start listening for requests within the timeout period of 0 seconds. Check the log output for error information.

Here are the things I tried none of them worked.

  1. Increased timeout in Startup.cs
  2. Set progress flag to true in agular.json
  3. Tried echo in ng serve command
  4. Tried --aot and --prod flags in ng build
  5. Upgraded global version of Angular to 11.0.4
  6. Removed externally installed node.js
  7. Setup environment variable to point node.js and ng path from the visual studio environment.
  8. angular/angular-cli#16961 (comment)

https://developercommunity.visualstudio.com/t/Angular-1104--Net-50-Giving-Timeout/1393855

@svrooij
Copy link

svrooij commented Apr 9, 2021

@heart2friend as a last try you can always start the angular process in a different terminal and switch the spa service to running on developer port.

@antkers
Copy link

antkers commented Apr 9, 2021

This workaround fixed it in my case:
https://stackoverflow.com/a/61454189

@blogcraft
Copy link

@heart2friend updating from .Net Core 3.1 to .Net5 fixed it for me.

@heart2friend
Copy link

@heart2friend as a last try you can always start the angular process in a different terminal and switch the spa service to running on the developer port.

Thank you @svrooij it worked. This shouldn't be the ideal solution but it's working is lot more for me.

For those who are struggling with same problem here is the interim solution

  1. Run the angular app using the command prompt (ng serve) from the ClienApp directory.
  2. Replace spa.UseAngularCliServer(npmScript: "start"); with spa.UseProxyToSpaDevelopmentServer("http://localhost:4200"); in Startup.cs file.

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");
                spa.UseProxyToSpaDevelopmentServer("http://localhost:4200");
            }
        });

This works like a charm!

@SkrupSulten
Copy link

@benelliott Thanks, your fix is the only solution that works for me. There is one issue though. The Node.js process is kept alive after closing the debug session in VS Code. If I restart a few times I soon run out of memory and the CPU usage skyrockets.

Is there a way to kill the Node.js process?

Right now I'm debating whether to give up and just start the .Net part and frontend parts separately.

@bthharper
Copy link

Has there been any progress on this?

I have several developers with exactly this problem and all the workarounds are no longer working. This does seem to have become worse with Angular 12, where the compilation time has increased.

I am now resorting to running the angular client separately before running the hosting application in the IDE.

@SkrupSulten
Copy link

@bthharper

Our fix was to have this script in package.json

"start": "ngserve",

And then a file ngserve.cmd with the following:

@echo ** Angular Live Development Server is listening on localhost:%~2, open your browser on http://localhost:%~2/ **
ng serve %1 %~2

We have no issues now, but an actual fix from MS would of course be better.

@mkArtakMSFT
Copy link
Contributor

Closing this as we've changed the approach how the SPA project templates work now. You can find more details about this in the issue tracking that work: #27887

@ghost ghost locked as resolved and limited conversation to collaborators Sep 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
affected-most This issue impacts most of the customers area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates bug This issue describes a behavior which is not expected - a bug. feature-spa investigate severity-major This label is used by an internal tool
Projects
None yet
Development

No branches or pull requests