-
Notifications
You must be signed in to change notification settings - Fork 517
Add new Angular CLI-based template #1288
Description
The Angular template shipped with .NET Core 2.0 originated well before @angular/cli came on to the scene. Even when @angular/cli was first shipped, it was unclear whether it would become the de facto standard way to build real-world Angular apps. But now it seems the Angular community largely sees the CLI as the preferred approach, and it has stabilised and matured into something you actually can use in real-world development scenarios.
So, even though the ASP.NET Core Angular template has pretty much all the same features as @angular/cli such as HMR, AoT on publish, Karma tests, etc. (and in fact even some features that the CLI lacks, such as out-of-the-box server-side prerendering), it would be advantageous if our template achieved that stuff using @angular/cli rather than having its own implementation. The key benefit is that developers will have an even more typical project setup, so basically all online tutorials, StackOverflow posts, etc., will apply without any modification.
Approach
The idea is for an updated dotnet new angular template to use a new SpaServices feature called Angular CLI middleware instead of the existing Webpack middleware. So it will still be a single ASP.NET Core project with the Angular part in a subdirectory called ClientApp, but now when the browser makes requests for content under /dist, we will pass through the request to an instance of @angular/cli's ng serve process. As such, the output and behaviour will be identical to what you'd get if you ran ng serve directly, and all the same config and features apply. If you wanted, you could even take your ClientApp directory out of your project and run it manually with ng serve, since it's literally just a standard @angular/cli project. Likewise you can ng eject it if you don't want to use the Angular CLI for some reason (and then use Webpack middleware like before if you want).
Of course, because you then have a standard Angular CLI project, you can use all other CLI features such as ng generate, ng lint, etc., without anything being different just because you're also using ASP.NET.
We would also integrate with Angular CLI when you publish your app. That is, a single dotnet publish command (or the Visual Studio equivalent option) would not only publish the .NET part but would also automate the process of using ng build -prod, putting the output in the right places to be served in production. Likewise, server-side prerendering would also be achieved by a call into Angular CLI.
Note: This would not be a breaking change. The SpaServices package will continue to work exactly the same with existing applications created using the .NET Core 2.0.0 template - this scenario remains fully supported.
Tasks
- Add
BuildServerSideRendererflag in csproj - Add new API for supplying custom data to prerenderer
- Support "proxy only" mode for AngularCliMiddleware, so you can have an
ng serveprocess running separately and not restarted on each C# code change. Ideally, decouple the proxying from the Angular CLI-specific bits so it can be reused with other SPA frameworks. - Consider whether it's practical to proxy the HMR endpoint. If not, this will be difficult to use from inside a Docker container (or at least requires extra configuration). Update: it does now proxy, so should work fine in Docker.
- Try to get CLI's progress display reflected in the console.
- Ensure that any errors occurring in angular-cli-middleware.js are passed back upstream. This also includes the CLI writing to stderr.
- Stop hard-coding CLI options in angular-cli-middleware.js. Either have a .NET API for configuring them, or better, call a
scriptinpackage.json(in which case, make the task name appear explicitly in the C# source so people can discover what it does). - Make sure the
npmchild processes aren't left behind on exit, including when usingdotnet watch, including on Mac/Linux - Get SSR working with publish by default. Waiting on Easy "ng build" improvements to make "platform":"server" work well on Windows & Visual Studio angular/angular-cli#7903
- Consider whether it's desirable to have
package.jsonandnode_modulesat project root (is this necessary for VS to do auto-restore?). If so, need to support findingnode_modulesin ancestor directories usingrequire-from-string-type approach (Resolve node modules in parent directories #154), since Angular app will be in subdirectory. Update: Not doing this - it's impractical. Angular CLI is hardcoded to assumenode_modulesis in the project root (e.g., seegetBrowserConfiginmodels\webpack-configs\browser.jsline 25), so we'd need to have the .NET project root as the Angular CLI project root, which means merging the folder structures (super ugly, and violates the intended separation), or having an extremely nonstandard Angular CLI config to have it fetch all sorts of things from a special subdirectory (violates the idea of it being a standard Angular CLI project). Instead, we'll rely on the.csprojcontaining instructions to do the applicablenpm installin theClientAppsubdir during build when necessary. - Figure out how the APIs would look if someone wanted
index.htmlto be a server-rendered cshtml page instead. Update: Not supporting this. Doesn't really make sense. - See if it's possible to detect efficiently whether the
<base href>matches thePathBaseof the incoming request, and if not, fail with a clear message. Alternatives include rewritingindex.htmldynamically to inject a<base href>based on the per-requestPathBase, or just rely on people reading docs to know they have to configure this manually before publishing. - Ensure the right set of files are appearing in VS's Solution Explorer (e.g.,
package.jsonshould be there) - Add shrinkwrap
- Fix the bootstrap nav button in the Angular templates (and check it works in the others)
- Ship preview
Pre-preview (try it)
You can now try this out. For instructions, please see #1288 (comment)