-
Notifications
You must be signed in to change notification settings - Fork 519
Feature/stevesa/spaservices extensions package #1367
Feature/stevesa/spaservices extensions package #1367
Conversation
Following @Eilon's feedback, I've reintroduced the The difference is that instead of attaching extra SPA middleware to the This more closely parallels how other nested-config patterns work in ASP.NET (e.g., A further consequence is that it's more constraining about how other SPA-related middleware can be used. It's now not possible to use middleware like |
@SteveSanderson is there a simple way to load the new template in beta or preview? I am setting up a new project and have some time on my side to test your template out |
Same here. I’m setting up a new POC project and I would love to start testing the new template with angular-cli |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks good. Let's chat about a few of my comments in person.
public DefaultSpaBuilder(IApplicationBuilder applicationBuilder, string sourcePath, string urlPrefix) | ||
{ | ||
ApplicationBuilder = applicationBuilder | ||
?? throw new System.ArgumentNullException(nameof(applicationBuilder)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you use using
, bro?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO: Fix
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
try | ||
{ | ||
openBrowserLine = await npmScriptRunner.StdOut.WaitForMatch( | ||
new Regex("open your browser on (http\\S+)"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regex? We should discuss. 😭
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO: Add timeout to the regex
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
} | ||
} | ||
|
||
#pragma warning disable CS0649 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm why would this warning come up?
Field 'field' is never assigned to, and will always have its default value 'value'
The compiler detected an uninitialized private or internal field declaration that is never assigned a value.
Is Port never read? Or is it read via reflection somewhere (e.g. via serialization)?
If that's the case, should add a comment stating that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO: Add comment clarifying what CS0649 means
TODO: Add comment saying why it's used here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
public static void UseSpaPrerendering( | ||
this ISpaBuilder spaBuilder, | ||
string entryPoint, | ||
ISpaPrerendererBuilder buildOnDemand = null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a lot of optional params, which can cause major headaches if we ever need to add new parameters in terms of breaking changes (not impossible, just difficult and ugly). Any concerns here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO: Change UseSpaPrerendering to take an options object callback
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
/// <summary> | ||
/// Gets or sets the URL, relative to <see cref="UrlPrefix"/>, | ||
/// of the default page that hosts your SPA user interface. | ||
/// The typical value is <c>"index.html"</c>. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of typical
maybe just say it's the default
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
TODO: On UseSpa, remove the defaultPage optional param |
var buf = new char[8 * 1024]; | ||
while (true) | ||
{ | ||
var chunkLength = await _streamReader.ReadAsync(buf, 0, buf.Length); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use ReadLineAsync?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because we want notifications of both partial-line chunks (for progress updates) and complete lines (that can be forwarded to the ILogger
).
…ew runtime functionality needed for updated templates until 2.1 ships
…endencies" because it breaks the build. Will need to find a different way to enforce this. This reverts commit 105422b.
…the app is shutting down
…ly it to the boot function
…o go via NodeServices)
…of AngularCliMiddleware
…affect public API.
…ry to keep restarting Angular CLI etc. on C# changes
…onditional' any more. This is internal, so the name change is fine.
87eb919
to
eb403ed
Compare
…ld basically always need to use it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code changes look good to me. Let's review the API/usage this afternoon.
Further CR feedback:
|
…fix/SourcePath from inside the callback
… string for the URI
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The updated codes continue to look good. Awaiting the final updates for final actual sign-off.
@Eilon Should be ready for final approval now |
…FileProvider to support SPAs not served from wwwroot (e.g., React).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Final-approved.
@Eilon Made a few final tweaks before merging. Will chat when I spot you around. |
{ | ||
throw new ArgumentException($"The value for {nameof(DefaultPage)} cannot be null or empty."); | ||
throw new ArgumentNullException($"The value for {nameof(DefaultPage)} cannot be null or empty."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change back to ArgumentException
- this is also thrown for empty strings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well spotted. Done.
This line: Is causing my site to fail every time, unless I manually stop the browser quickly, after pressing F5 (or Ctrl F5) in Visual Studio Because of the fact that the console window appears and states:
The browser opens immediately, as it starts to do the build. However, the build definitely does not finish in 50 seconds, so then it times out (displaying an error while building) and gets stuck unusable due to hitting the exception for the timeout. The browser should not be opening up until the Thanks |
@SpeedHighway can you log this in a new issue? That'll make it easier for us to track and investigate. |
Our next update to the Angular template changes it substantially so that it's entirely based around Angular CLI. This much better matches the desired usage patterns. The community has welcomed this proposed change. We will very likely do the same thing for the React template, basing an updated template around the
create-react-app
tool.The core implementation idea is to stop coupling the SPA APIs to MVC concepts (e.g., before, the routing was integrated with MVC routing, and prerendering was implemented as a tag helper), and instead have a set of middleware APIs that handle:
index.html
), thereby making client-side routing workAll of these new middleware APIs work equally well in MVC applications as in Razor Pages applications. For an example of their usage, please see https://github.com/aspnet/templating/blob/feature/stevesa/angular-cli-template/src/Microsoft.DotNet.Web.Spa.ProjectTemplates/content/Angular-CSharp/Startup.cs#L43
To support all this, we need some new runtime pieces. To allow for the possibility of shipping this out-of-band before the 2.1 release, 100% of the new runtime code is in a new package,
Microsoft.AspNetCore.SpaServices.Extensions
. This can ship with a dependency onSpaServices
version 2.0.0, without any loss of back-compatibility (sinceSpaServices
itself doesn't need to change). Later, we'll migrate the new functionality intoSpaServices
, and reduceSpaServices.Extensions
to a set of type forwarders that exists only for back-compatibility (and at that point, the templates will no longer reference it for new applications).As you'll see, the majority of code here is purely
internal
so we reserve the option to change implementation details pretty broadly once we get some preview feedback (and even after RTM). So for this review, I'm mostly keen on getting feedback on the public API design choices, though of course feel free to review whatever aspects of it you want.