Closed SteveSandersonMS closed 6 years ago
Totally agree! I've been quite annoyed lately, fighting some CORS-related issues, I still cannot find a solution to (due to having both back- and front-end separated).
I would have loved to have them combined, for server-side-rendering too, but it was an intentional decision (which may seem detrimental now), to utilize the "mainstream" @angular/cli
for boilerplate generation.
My "risk assessment" on trying to predict the future, says @angular/cli
is likely a safer dependency in the long run.
I think the perfect scenario would be if dotnet new angular
relied on the @angular/cli
, as suggested, in such a way that you could at any time extract only the Angular project and continue using it only with @angular/cli
. Is that feasible?
Google's Angular already relies on Microsoft's TypeScript - can the teams coordinate it so @angular/cli
won't make unnecessary breaking changes so it's safe-ish to be embedded in JavaScriptServices :-) ? Or does it not work like that, lol. In any case, please take @SteveSandersonMS post very serious!
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.
This would simply be amazing...
@amivit I don't have my back- and front-end in separate projects anymore but when I did, if I recall it was just a case of having:
services.AddCors(options => options.AddPolicy("MyPolicy", p => p.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
));
.. in the right place in ConfigureServices() and:
app.UseCors("MyPolicy");
...in Configure()
@SteveSandersonMS We also have Universal support in the CLI now, but I'm wondering if we will be able to pipe that into aspnet somehow as well? Let me know if we can meet up again when you have some time I'd love to help anyway I can to merge the two processes, or help add any hooks Aspnet would need from the CLI.
This would be ideal in letting the CLI community handle all upcoming Angular aspects of the template as well, improvements, etc 👍
Exciting times!
@peterdobson that works for anything except POST. POST is special since the Access-Control-Allow-Origin NEEDS an explicit reference to the requests Origin. So I made an explicit Origin which works fine for everything, except POST. The issue occurs because browsers by design, strip the initial OPTIONS request of all headers (such as authorize). For some stupid reason, my app when deployed to IIS, expects the Authorize even on the OPTIONS, and returns 401 unauthorized. If I enable anonymous access globally on the ng frontend, the problem goes away. Which is fine for this internal tool, when the API is still secure. I guess it's more of an IIS issue, and I don't want to hijack this thread, which I'm already in the process of doing :/
aspnetcore-angular2-universal seems cool, but way too bleeding edge for me to dare use for anything production. I'd prefer relying on @angular/cli
with asp.net/JavaScriptServices
@SteveSandersonMS Is this a plan feature or already release? Because choosing the angular template today would get the webpack middleware, which has many bug. Upgrading to bootstrap 4 took me the whole afternoon without success. Npm will not install bootstrap 4 in visual studio 2017 enterprise. So went to command line and did it, then SpaService would not webpack the bootstrap 4 into the bundle. Just gave up in the end.
@wangkanai it is not already released
@SteveSandersonMS this is that i've been waiting for :) nice 👍
This also solves questions around using environment variables/settings for client-side code. https://github.com/angular/angular-cli/wiki/stories-application-environments
In case anyone wants to see, I'm working on this here: https://github.com/aspnet/templating/tree/stevesa/angular-cli-template. Don't ask for support with getting or using it yet though - it's not ready 😄
This would be awesome! The production builds through angular cli are also very well optimized and also includes features such as hash file name.
@spboyer I could use that too. Had trouble getting it working well using the Angular CLI built in enviornments configs.
Fantastic news. For the last year, I've been avoiding javascript services since as Steve notes at top of this issue, many of us prefer the angular cli. I have been building my angular 2/4 with angular CLI in its own project and writing to an asp.net core wwwroot directory for production. But this missed all the tooling you've developed around javascript services, made integrated testing slow and split the angular app from my development process for the Api/MVC and IdentityServer projects.
Looking forward to seeing what you do with exposing angular cli, while maintaining other javascript services tooling (outside webpack),and config for the enclosing asp.net core project. My greatest concern would be to not interfere with the angular upgrade process - i.e. when I update the package.json with angular 5..6..7, that the coupling to asp.net core and javascript services stays loose enough, that the breaks I need to fix are angular specific.
Just saw a demo first look of this @Angularmix and it was simply awesome!! This is would definitely deliver great value to many developers who want to get into Angular using Asp.net Core but often struggle with the complicated processes of getting both technologies to coordinate. Thank you @SteveSanderson and Asp.net Team!
@SteveSandersonMS where can I find a sample project? Looks like the URL feed you provided above is no longer available: Link
It seemed to have moved here: https://github.com/aspnet/templating/tree/feature/stevesa/angular-cli-template
@SteveSandersonMS is ALWAYS amazing, and this feature is going to be SO BIG!
Thank you @Meligy.
Agreed. Recently blogged about how to make existing .NET Core SPA templates to support Angular-cli https://programmium.wordpress.com/2017/10/02/ng-add-angular-cli-to-net-core-angular-template/ but this project is going to be a great benefit..
Thanks @SteveSandersonMS for the heads up! Digging into this now.
@SteveSandersonMS please target Angular 5 and aspnetcore-engine 5. Angular 5 is currently in Rc6 and aspnetcore-engine 5 is currently in 5.0.0-beta.4 hopefully by the time this template is released Angular 5 and aspnetcore-engine 5 would be production ready.
Really excited to hear about Angular-cli integration.
@SteveSandersonMS Angular CLI now has support for Lazy Loading routes for Server-side rendering, I hope its support can also bee added to the template.
@SteveSandersonMS -- Shawn Wildermuth posted a blog about doing this with ASP .Net Core, Entity Framework Core and the Angular CLI [https://wildermuth.com/2017/07/10/ASP-NET-Core-2-VS2017-Angular-CLI ]. There is also a corresponding PluralSight course for this as well.
Hi guys, I am wondering how to try the branch that Steve mentioned for cli integration. I have downloaded the source but when I navigate into directory, there is no csproj file "Angular-CSharp". I believe there is a different way to run these template? :)
@asadsahi may be this is what you are looking for https://github.com/aspnet/Templates/wiki/Building-and-Running
@naveedahmed1 thanks, will give it a shot.
Hi all, I have a small application developed from angular spa template ("dotnet new angular") and I would like to use the new template that @SteveSandersonMS has created, or at least to start a new application using the template. Can someone guide me how to do it?
@asadsahi Please let us know if you get it to work. I followed the steps at https://github.com/aspnet/Templates/wiki/Building-and-Running but I do not get an "intermediate" folder with the test projects mentioned in the documentation. I'm still trying to figure out how to test this.
Tried it,
dev branch: build it takes ages ended up with some failing tests lost hope Waiting for some ultimate thingy to run. :)
Steve isn't done with it. Microsoft is still working on the PRs just yesterday
It is not released yet
@asadsahi @jxvalenz
@jrmcdona I know, was just saying :)
FYI https://github.com/aspnet/JavaScriptServices/issues/1258#issuecomment-339652427
There isn't a specific ETA for release, but hopefully we will have a preview out in about a month.
Got checked both node vs dotnet core - last one seams to be faster and more stable, so will be nice to have out of the box working template just to run it in production environment
@mac2000 what are you referring here? the spa services cli template?
@asadsahi yep, now the challenge is marry spa services template with angular cli, so went here, just wanted to share what we was able to achieve in case of anyone will need to check that also, seems that dotnet core utilizing more resources than single threaded node so out of the box dotnet core works better under load and to us seems like a preferable way to host apps
On the note of performance I just want to briefly mention that my F5 experience to run the current SPA service angular template (not the cli based) is extreeeeeeeeeeeeeeeeeeeeemly slow. Not sure what others are experiencing overall. If more people are having slow performance, then I can raise another issue on this?
slow perf on F5
I noticed it too. I then worked on a project that used the Angular CLI
and it seemed to startup much quicker.
What I eventually noticed is the Angular CLI
build is running the webpack
build so when I opened the browser everything is ready to go. With the .Net solution
, it does the webpack
build after VS has attached itself so the browser load time is really slow.
If I measured it, I would think I would see something like this:
Type | Build Time | Initial Browser Load Time | Total Time |
---|---|---|---|
.Net | 15secs | 1min | 1min 15secs |
.Angular CLI | 1 min 12 secs | 3 secs | 1min 15secs |
@asadsahi is that what you mean but extremely slow?
What I mention is that using dotnet core for production only purposes, there is no need to run it localy why not just use cli? So I'm looking for a way to use cli for local development and use dotnet core as a platform to run application on production with server side rendering nothing more. Only one thing is left is how to marry cli with core
@mac2000: I do what you describe (use asp.net core just for production). I would hope for something similar from a Javascript Services Template.
I have an angular-cli frontend project, and an asp.net core backend project.
The frontend is developed/tested in VS Code, and with the angular-cli commands (ng serve. ng test).
To generate the production code into the backend project wwwroot, I use the following command:
ng build --prod --extract-css=false --output-hashing=none --delete-output-path=false --output-path="../backend/wwwroot/"
The backend project has an index.cshtml file (with asp.net core 2.0 - I'd use a Razor Page) that references the angular files written to wwwroot.
@mac2000 is it something like that you want : https://medium.com/@levifuller/building-an-angular-application-with-asp-net-core-in-visual-studio-2017-visualized-f4b163830eaa?
@paddyfink nope what I looking for is to marry results of ng new acme
and dotnet new angular
- second one has build in server side rendering but luck of cli features
@mac2000 That's exactly what the updated template here does.
@SteveSanderson I'm sorry but after looking on all links in this thread I did not managed where is it, e.g. is it in pull request somewhere or in separate repository, will be so nice to have link somewhere in initial post if possible so people like me wont bother with such questions again and again
@mac2000 It's not released yet. https://github.com/aspnet/JavaScriptServices/issues/1288#issuecomment-343210705
@SteveSanderson is it possible to try it whatever the state it is in. Last time I tried building the templates project, but couldn't build it on my machine. Anything which allows to just run it easily.
Make sure you have .NET Core 2.0.0+ SDK installed. Check this by running dotnet --version
in a command prompt. Also you need Node.js installed (check by running node -v
).
In your command prompt, run:
dotnet new --install Microsoft.DotNet.Web.Spa.ProjectTemplates::2.0.0-preview1-final
Now you can create projects with it:
mkdir my-new-app
cd my-new-app
dotnet new angular
or dotnet new react
or dotnet new reactredux
Views
directory, and its Startup.cs
contains a call to app.UseSpa
, then you do have the new template.dotnet build
(note: on the first run, this will do the NPM restore, which can take a few minutes)ASPNETCORE_Environment
to Development
(e.g., set ASPNETCORE_Environment=Development
in Windows (non-Powershell prompt) or export ASPNETCORE_Environment=Development
on macOS/Linux)dotnet run
Optionally, if you're on Windows, you can open the generated .csproj
in Visual Studio 2017 and run the project from there.
Note that these new SPA templates work by running the SPA framework's development server in the background (instead of Webpack dev middleware). So for the Angular template, it runs the Angular CLI server in the background, and for the React templates, it runs the dev server configured by create-react-app. If you run your app from a command prompt (i.e., not launching in IISExpress from VS), then you'll see it display the compilation progress.
There are various other things you can do:
Startup.cs
. In the React/ReactRedux templates, SSR is not a built-in feature because create-react-app itself does not have that feature.dotnet publish -c Release
, or use VS's "Publish" UI) then it will internally build a production-ready version of the client app too, so you'll be serving fully optimised code.ClientApp
subdirectory, you can run whatever commands are applicable to your SPA framework. For example, for Angular, you can run things like ng test
, ng e2e
, ng lint
, or for React/ReactRedux you can run npm test
etc.
ClientApp
subdirectory, not at the ASP.NET project root, because the entire client-side app exists in ClientApp
.cd ClientApp
then run npm start
), and change your Startup.cs
so that instead of calling spa.UseAngularCliServer
or spa.UseReactDevelopmentServer
, you instead call spa.UseProxyToSpaDevelopmentServer("http://localhost:4200");
(update the port number as appropriate). Then you won't need to wait for the Angular/React/etc app to rebuild each time you restart the ASP.NET app.ClientApp
subdirectory out of the project to another location. Then you can run things like ng serve
or npm start
and it will be a pure SPA with no ASP.NET.If you want to go back to the existing RTM SPA template, then you can delete the directory .templateengine
which is at the root of your user directory. For example, on Windows, that might be at c:\Users\yourname\.templateengine
. Then next time you run dotnet new
it will reset the templates to the default ones shipped in the SDK.
If you discover any glaring bugs, please let us know. Equally important, if you don't discover any bugs and in fact it appears to work nicely, then please post to say that too, as it gives us extra confidence to ship this soon.
Genius work, thanks @SteveSandersonMS
Just ran first application with this template, and it works like a charm. First thing I have noticed in console is this error:
It isnt' affecting anything in first observation. Client rebuilds fine, server side code works fine. Not sure if this is something specific on my machine or anything else.
here is my environment info:
dotnet --info
.NET Command Line Tools (2.0.0)
Product Information:
Version: 2.0.0
Commit SHA-1 hash: cdcd1928c9
Runtime Environment:
OS Name: Windows
OS Version: 6.1.7601
OS Platform: Windows
RID: win7-x64
Base Path: C:\Program Files\dotnet\sdk\2.0.0\
Microsoft .NET Core Shared Framework Host
Version : 2.0.0
Build : e8b8861ac7faf042c87a5c2f9f2d04c98b69f28d
Here is debug log related to this error from console:
at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.<Invoke>d__7.MoveNext()
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware:Error: An unhandled exception has occurred while executing the request
System.PlatformNotSupportedException: The WebSocket protocol is not supported on this platform.
at System.Net.WebSockets.WebSocketValidate.ThrowPlatformNotSupportedException()
at System.Net.WebSockets.WebSocketHandle.CheckPlatformSupport()
at System.Net.WebSockets.ClientWebSocket..ctor()
at Microsoft.AspNetCore.SpaServices.Extensions.Proxy.SpaProxy.<AcceptProxyWebSocketRequest>d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.SpaServices.Extensions.Proxy.SpaProxy.<PerformProxyRequest>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Builder.SpaProxyingExtensions.<>c__DisplayClass2_0.<<UseProxyToSpaDevelopmentServer>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.<Invoke>d__7.MoveNext()
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 POST http://localhost:5000/sockjs-node/637/osh1d2ij/xhr_streaming?t=1511269032941 0
Request starting HTTP/1.1 POST http://localhost:5000/sockjs-node/637/osh1d2ij/xhr_streaming?t=1511269032941 0
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 209.7994ms 500 text/html; charset=utf-8
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 209.7994ms 500 text/html; charset=utf-8
Awesome work @SteveSandersonMS ! Just some quick feedback.
I enabled SSR, by uncommenting the code in startup file and by setting <BuildServerSideRenderer>
property value to 'true'
in my_new_app.csproj
And then tried to publish, but when I deploy it, its throwing 500 error. Below is the log file:
Hosting environment: Production
Content root path: C:\inetpub\wwwroot
Now listening on: http://localhost:28163
Application started. Press Ctrl+C to shut down.
fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[0]
An unhandled exception has occurred: Can't resolve all parameters for e: (?, [object Object]).
Error: Can't resolve all parameters for e: (?, [object Object]).
at u (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:322479)
at e.Nw2y.e._getDependenciesMetadata (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:496723)
at e.Nw2y.e._getTypeMetadata (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:494503)
at e.Nw2y.e.getNonNormalizedDirectiveMetadata (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:487640)
at e.Nw2y.e._getEntryComponentMetadata (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:498828)
at C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:498583
at Array.forEach (<anonymous>)
at e.Nw2y.e._getEntryComponentsFromProvider (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:498555)
at C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:497797
at Array.forEach (<anonymous>)
Microsoft.AspNetCore.NodeServices.HostingModels.NodeInvocationException: Can't resolve all parameters for e: (?, [object Object]).
Error: Can't resolve all parameters for e: (?, [object Object]).
at u (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:322479)
at e.Nw2y.e._getDependenciesMetadata (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:496723)
at e.Nw2y.e._getTypeMetadata (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:494503)
at e.Nw2y.e.getNonNormalizedDirectiveMetadata (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:487640)
at e.Nw2y.e._getEntryComponentMetadata (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:498828)
at C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:498583
at Array.forEach (<anonymous>)
at e.Nw2y.e._getEntryComponentsFromProvider (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:498555)
at C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:497797
at Array.forEach (<anonymous>)
at Microsoft.AspNetCore.NodeServices.HostingModels.HttpNodeInstance.<InvokeExportAsync>d__7`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Microsoft.AspNetCore.NodeServices.HostingModels.OutOfProcessNodeInstance.<InvokeExportAsync>d__13`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Microsoft.AspNetCore.NodeServices.NodeServicesImpl.<InvokeExportWithPossibleRetryAsync>d__10`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.AspNetCore.NodeServices.NodeServicesImpl.<InvokeExportWithPossibleRetryAsync>d__10`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Builder.SpaPrerenderingExtensions.<>c__DisplayClass0_0.<<UseSpaPrerendering>b__1>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>d__6.MoveNext()
fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[0]
An exception was thrown attempting to execute the error handler.
Microsoft.AspNetCore.NodeServices.HostingModels.NodeInvocationException: Can't resolve all parameters for e: (?, [object Object]).
Error: Can't resolve all parameters for e: (?, [object Object]).
at u (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:322479)
at e.Nw2y.e._getDependenciesMetadata (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:496723)
at e.Nw2y.e._getTypeMetadata (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:494503)
at e.Nw2y.e.getNonNormalizedDirectiveMetadata (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:487640)
at e.Nw2y.e._getEntryComponentMetadata (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:498828)
at C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:498583
at Array.forEach (<anonymous>)
at e.Nw2y.e._getEntryComponentsFromProvider (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:498555)
at C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:497797
at Array.forEach (<anonymous>)
at Microsoft.AspNetCore.NodeServices.HostingModels.HttpNodeInstance.<InvokeExportAsync>d__7`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Microsoft.AspNetCore.NodeServices.HostingModels.OutOfProcessNodeInstance.<InvokeExportAsync>d__13`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Microsoft.AspNetCore.NodeServices.NodeServicesImpl.<InvokeExportWithPossibleRetryAsync>d__10`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.AspNetCore.NodeServices.NodeServicesImpl.<InvokeExportWithPossibleRetryAsync>d__10`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Builder.SpaPrerenderingExtensions.<>c__DisplayClass0_0.<<UseSpaPrerendering>b__1>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>d__6.MoveNext()
fail: Microsoft.AspNetCore.Server.Kestrel[13]
Connection id "0HL9GUBPQSO55", Request id "0HL9GUBPQSO55:00000001": An unhandled exception was thrown by the application.
Microsoft.AspNetCore.NodeServices.HostingModels.NodeInvocationException: Can't resolve all parameters for e: (?, [object Object]).
Error: Can't resolve all parameters for e: (?, [object Object]).
at u (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:322479)
at e.Nw2y.e._getDependenciesMetadata (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:496723)
at e.Nw2y.e._getTypeMetadata (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:494503)
at e.Nw2y.e.getNonNormalizedDirectiveMetadata (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:487640)
at e.Nw2y.e._getEntryComponentMetadata (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:498828)
at C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:498583
at Array.forEach (<anonymous>)
at e.Nw2y.e._getEntryComponentsFromProvider (C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:498555)
at C:\inetpub\wwwroot\ClientApp\dist-server\main.bundle.js:1:497797
at Array.forEach (<anonymous>)
at Microsoft.AspNetCore.NodeServices.HostingModels.HttpNodeInstance.<InvokeExportAsync>d__7`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Microsoft.AspNetCore.NodeServices.HostingModels.OutOfProcessNodeInstance.<InvokeExportAsync>d__13`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Microsoft.AspNetCore.NodeServices.NodeServicesImpl.<InvokeExportWithPossibleRetryAsync>d__10`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.AspNetCore.NodeServices.NodeServicesImpl.<InvokeExportWithPossibleRetryAsync>d__10`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Builder.SpaPrerenderingExtensions.<>c__DisplayClass0_0.<<UseSpaPrerendering>b__1>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Server.IISIntegration.IISMiddleware.<Invoke>d__11.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Hosting.Internal.RequestServicesContainerMiddleware.<Invoke>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Frame`1.<ProcessRequestsAsync>d__2.MoveNext()
Application is shutting down...
@asadsahi I am not seeing any error in console, so it could be system specific.
.NET Command Line Tools (2.0.3)
Product Information:
Version: 2.0.3
Commit SHA-1 hash: 12f0c7efcc
Runtime Environment:
OS Name: Windows
OS Version: 10.0.15063
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\2.0.3\
Microsoft .NET Core Shared Framework Host
Version : 2.0.3
Build : a9190d4a75f4a982ae4b4fa8d1a24526566c69df
Great work!!! I can't wait! Loved reading the "other features". Everything looks perfect - the mindset is on point. Proper integration with low-coupling. Beautiful 👍
Microsoft.DotNet.Web.Spa.ProjectTemplates.2.0.0-preview0-t0056f783d.nupkg
, Core 2.0.3 SDK
, node 9.1.0
. Builds and runs perfectly fine for me. Both from commandline & Visual Studio 2017 - without @asadsahi's websocket console error.
I have the same SSR issue as @naveedahmed1, when building for production. The site cannot load with SSR enabled at all. Works fine in development mode, however.
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 newSpaServices
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 calledClientApp
, but now when the browser makes requests for content under/dist
, we will pass through the request to an instance of@angular/cli
'sng serve
process. As such, the output and behaviour will be identical to what you'd get if you ranng serve
directly, and all the same config and features apply. If you wanted, you could even take yourClientApp
directory out of your project and run it manually withng serve
, since it's literally just a standard@angular/cli
project. Likewise you canng 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 usingng 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
BuildServerSideRenderer
flag in csprojng serve
process 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.script
inpackage.json
(in which case, make the task name appear explicitly in the C# source so people can discover what it does).npm
child processes aren't left behind on exit, including when usingdotnet watch
, including on Mac/Linuxpackage.json
andnode_modules
at project root (is this necessary for VS to do auto-restore?). If so, need to support findingnode_modules
in ancestor directories usingrequire-from-string
-type approach (#154), since Angular app will be in subdirectory. Update: Not doing this - it's impractical. Angular CLI is hardcoded to assumenode_modules
is in the project root (e.g., seegetBrowserConfig
inmodels\webpack-configs\browser.js
line 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.csproj
containing instructions to do the applicablenpm install
in theClientApp
subdir during build when necessary.index.html
to be a server-rendered cshtml page instead. Update: Not supporting this. Doesn't really make sense.<base href>
matches thePathBase
of the incoming request, and if not, fail with a clear message. Alternatives include rewritingindex.html
dynamically 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.package.json
should be there)Pre-preview (try it)
You can now try this out. For instructions, please see https://github.com/aspnet/JavaScriptServices/issues/1288#issuecomment-346003334