Angular SPA SSR Template bug with Angular 6 #1619
Description
I converted this template https://docs.microsoft.com/en-us/aspnet/core/spa/angular?view=aspnetcore-2.1&tabs=visual-studio to Angular 6. Everything worked fine initially, but then an update to @angular-devkit/build-angular
npm package (from version 0.5.5 to 0.5.6) broke it.
The reason I'm not submitting this issue to the Angular repo is I think it's actually a bug in https://github.com/aspnet/JavaScriptServices/blob/dev/src/Microsoft.AspNetCore.SpaServices.Extensions/Util/EventedStreamReader.cs that wasn't noticed until now. Basically the AngularCliBuilder.cs waits for "ng build:ssr" to finish by watching the console output & looking for "Date" in the output. I haven't done a "diff" of the actual ASCII values in the console output between the two angular versions, but visually they look almost identical, except the new version has an extra newline, otherwise they look the same.
This is the error I'm getting:
Here's the visual difference between the console outputs:
working:
I need to research more, but I believe the issue is with this function in EventedStreamReader.cs:
private async Task Run()
{
var buf = new char[8 * 1024];
while (true)
{
var chunkLength = await _streamReader.ReadAsync(buf, 0, buf.Length);
if (chunkLength == 0)
{
OnClosed();
break;
}
OnChunk(new ArraySegment<char>(buf, 0, chunkLength));
var lineBreakPos = Array.IndexOf(buf, '\n', 0, chunkLength);
if (lineBreakPos < 0)
{
_linesBuffer.Append(buf, 0, chunkLength);
}
else
{
_linesBuffer.Append(buf, 0, lineBreakPos + 1);
OnCompleteLine(_linesBuffer.ToString());
_linesBuffer.Clear();
_linesBuffer.Append(buf, lineBreakPos + 1, chunkLength - (lineBreakPos + 1));
}
}
}
I think it should call OnCompleteLine(_linesBuffer.ToString()); a final time at the end of the function if there's anything still in the buffer.
I've created a repo for reproducing this at https://github.com/speige/Angular6DotNetCoreSpaTemplateBug
The "master" branch is the original angular 5 template. The "Angular6Working" branch is an straight upgrade to v6 with the @angular-devkit/build-angular
npm package on 0.5.5. The "Angular6broken" branch is identical except with @angular-devkit/build-angular
on 0.5.6
The "Angular6Working" branch might be useful in order to upgrade the official template to Angular 6 (still in RC, but should be oficially released any day now).
On a side note, for Angular6 upgrade, a change should be done in
https://github.com/aspnet/JavaScriptServices/blob/dev/src/Microsoft.AspNetCore.SpaServices.Extensions/AngularCli/AngularCliBuilder.cs
var npmScriptRunner = new NpmScriptRunner(
sourcePath,
_npmScriptName,
"--watch",
null);
The "--watch" is no longer a valid command line argument in Angular 6 CLI. I believe if you do "ng serve" it automatically does --watch, if you do "ng build" it doesn't.
I worked around this issue by changing the "build:ssr" command in my package.json from
"build:ssr": "ng build --configuration=production --project=ssr"
to
"build:ssr_ignore_dash_dash_watch_from_AngularCliBuilderDotCS": "ng build --configuration=production --project=ssr ",
"build:ssr": "npm run build:ssr_ignore_dash_dash_watch_from_AngularCliBuilderDotCS"
which basically causes the extra command line argument to be discarded before "ng build" is called. Otherwise Angular throws an error about an invalid command line argument.
I'll test my theory with EventedStreamReader.cs & assuming it fixes this issue I'll submit a pull request.