Skip to content
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

[Announcement] Obsoleting Microsoft.AspNetCore.SpaServices and Microsoft.AspNetCore.NodeServices #12890

Closed
danroth27 opened this issue Aug 5, 2019 · 307 comments
Labels
breaking-change feature-spa
Milestone

Comments

@danroth27
Copy link
Member

@danroth27 danroth27 commented Aug 5, 2019

ASP.NET Core supports integration with various single-page app (SPA) frameworks, including Angular, React, and React + Redux. Initially integration with these frameworks was accomplished with ASP.NET Core specific components that handled scenarios like server-side prerendering and integration with webpack. But as time went on, industry standards changed and the SPA frameworks each released their own standard command-line interfaces (e.g., Angular CLI, create-react-app).

When ASP.NET Core 2.1 was released in May 2018, we responded to the change in standards by providing a newer and simpler way to integrate with the SPA frameworks' own toolchains. This new integration mechanism exists in the package Microsoft.AspNetCore.SpaServices.Extensions and remains the basis of our Angular and React project templates since ASP.NET Core 2.1.

To clarify that the older ASP.NET Core specific components are not relevant or recommended, we are now officially obsoleting the pre-2.1 integration mechanism and marking the supporting NPM packages as deprecated.

The contents of the following NuGet packages have all been unnecessary since ASP.NET Core 2.1, and so are now being marked as obsolete:

  • Microsoft.AspNetCore.SpaServices
  • Microsoft.AspNetCore.NodeServices

For the same reason, the following NPM modules are being marked as deprecated:

  • aspnet-angular
  • aspnet-prerendering
  • aspnet-webpack
  • aspnet-webpack-react
  • domain-task

These packages will later be removed in .NET 5. If you are using these packages, please update your apps to use the functionality in Microsoft.AspNetCore.SpaServices.Extensions instead along with the functionality provided by the SPA frameworks you are using. To enable features like server-side prerendering and hot module reload please refer to the documentation for the corresponding SPA frameworks. The functionality in Microsoft.AspNetCore.SpaServices.Extensions is not obsolete and will continue to be supported.

@NotMyself
Copy link

@NotMyself NotMyself commented Aug 6, 2019

Is UseWebpackDevMiddleware going away with this change? Or UseSpaStaticFiles?

@flcdrg
Copy link
Contributor

@flcdrg flcdrg commented Aug 6, 2019

We've been using Microsoft.AspNetCore.NodeServices as a way of executing JavaScript in Node on the server from .NET Core - specifically by calling the InvokeAsync method(s).

We'd previously been using the ClearScript library (in an earlier .NET Framework project), but that does not yet support .NET Core/.NET Standard.

If Microsoft.AspNetCore.NodeServices goes away, our only alternative would probably be to fork the source code.

@CodeTherapist
Copy link

@CodeTherapist CodeTherapist commented Aug 6, 2019

Is UseWebpackDevMiddleware going away with this change? Or UseSpaStaticFiles?

@NotMyself As far as I understand UseWebpackDevMiddleware will go away and UseSpaStaticFiles will not.

Seriously, I liked this webpack middleware with HMR, because it accelerates the inner loop and is more comfortable instead of having two processes (dev server + ASP.NET Core app). It also reflects more the production running app - that is served by ASP.NET Core using e.g. Kestrel.
I use it with vuejs (started with this obsoleted template).

I would appreciate, when useful libraries aren't become obsolete after years of supporting it. That weaknesses the trust using a library. At least, I expect a comprehensive migration guide for those who using the obsolete libraries.

@Simon-Bull
Copy link

@Simon-Bull Simon-Bull commented Aug 6, 2019

We use the ISpaPrerenderer.RenderToString() functionality to server render a VueJS application, passing application context with the customDataParameter.

Is there a recommended migration path to move to functionality in Microsoft.AspNetCore.SpaServices.Extensions? This seems to use RenderToString() itself.

@bugproof
Copy link

@bugproof bugproof commented Aug 6, 2019

Any reason why there's no official vue project template?

@CodeTherapist
Copy link

@CodeTherapist CodeTherapist commented Aug 6, 2019

Any reason why there's no official vue project template?

@bugproof Maintaining templates isn't effortless. This has been discussed in issue: aspnet/JavaScriptServices/issues/412.

@Sebazzz
Copy link

@Sebazzz Sebazzz commented Aug 6, 2019

So how would HMR work with Webpack now? Webpack runs its own web server.

@ericgreenmix
Copy link
Contributor

@ericgreenmix ericgreenmix commented Aug 6, 2019

My company also uses the Microsoft.AspNetCore.NodeServices to execute JS from .Net. Is there a recommended alternative, if NodeServices is going away?

@alexdresko
Copy link

@alexdresko alexdresko commented Aug 6, 2019

I get the main gist of this issue, but losing UseWebpackDevMiddleware seems unfortunate. It works great for frameworks that don't have a CLI.

@atrauzzi
Copy link

@atrauzzi atrauzzi commented Aug 6, 2019

I'm not sure I understand how NodeServices is related to this? What if people want to run JS code from C# for their own purposes?

@NotMyself
Copy link

@NotMyself NotMyself commented Aug 6, 2019

@alexdresko I agree with you. UseWebpackDevMiddleware is a nice compromise to supporting multiple frameworks. I have been using it for around a year to do Vue.js development, example. It works quite nicely.

@danroth27
Copy link
Member Author

@danroth27 danroth27 commented Aug 6, 2019

Is UseWebpackDevMiddleware going away with this change? Or UseSpaStaticFiles?

@NotMyself The webpack middleware is part of Microsoft.AspNetCore.SpaServices and will be obsoleted as part of this change. The support for SPA static files is part of Microsoft.AspNetCore.SpaServices.Extensions and will continue to be supported.

@danroth27
Copy link
Member Author

@danroth27 danroth27 commented Aug 6, 2019

@flcdrg @atrauzzi @ericgreenmix Could you please share with us some details on how you are using NodeServices today? Why do you need to execute JavaScript on the server at runtime? If there is significant interest in this functionality it might be interesting to spin NodeServices off as a community driven project. Is that something any of you would be interested in taking on?

@manigandham
Copy link

@manigandham manigandham commented Aug 6, 2019

@danroth27

We use NodeServices to run some NPM packages that don't have equivalent .NET libraries and aren't worth a rewrite. This is one of the benefits as mentioned by the team before.

We also have a functions-as-a-service platform that we're building for customers to write their own custom logic in our app using Javascript. There are alternatives like Edge.js (which is not .net core compatible) but NodeServices makes this easy.

There's a lot of value in it and if it's not going to be maintained then we would definitely like to see it as a separate community project.

@jarroda
Copy link

@jarroda jarroda commented Aug 6, 2019

@danroth27 For the same reason that people do interop generally. In our case, we're using a PDF generation library to do reporting, because there is no equivalent available in netcore for linux platforms. As @manigandham points out, that was a general feature of the library.

@ericgreenmix
Copy link
Contributor

@ericgreenmix ericgreenmix commented Aug 6, 2019

@danroth27 As others have said, we use it to leverage various NPM packages that don't have equivalents in .Net.

As the repositories readme states:

This provides a fast and robust way for .NET code to run JavaScript on the server inside a Node.js environment. You can use this to consume arbitrary functionality from NPM packages at runtime in your ASP.NET Core app.

What led to the decision of deciding to obsolete the NodeServices without an equivalent replacement? It seems like an oversight to me.

@danroth27
Copy link
Member Author

@danroth27 danroth27 commented Aug 6, 2019

What led to the decision of deciding to obsolete the NodeServices without an equivalent replacement?

@ericgreenmix Our primary scenario for building NodeServices was to enable integration between SPA frameworks and ASP.NET Core for things like like server-side prerendering and HMR. Since we now integrate with the CLIs for Angular and React directly this functionality is no longer needed for these specific scenarios. Providing NodeServices as a generic way to into JS from .NET Core is not something we want to maintain long term.

@danroth27
Copy link
Member Author

@danroth27 danroth27 commented Aug 6, 2019

if it's not going to be maintained then we would definitely like to see it as a separate community project.

@manigandham Makes sense. We certainly would encourage folks that are interested in continuing to maintain this functionality as a community based project to do so. If such a community project were to spin up it is more than welcome to use the existing NodeServices code as a starting point with the appropriate changes to the namespaces and package names. We'd be happy to point folks that are interested in this functionality to whatever the community comes up with.

@danroth27
Copy link
Member Author

@danroth27 danroth27 commented Aug 6, 2019

UseWebpackDevMiddleware is a nice compromise to supporting multiple frameworks. I have been using it for around a year to do Vue.js development, example. It works quite nicely.

@NotMyself We'd like to enable the .NET + Vue community to ship a Vue template that integrates with the Vue CLI similar to what we do for Angular and React. I believe we still have some functionality to make public to make that reasonable to do, but I think that's something we'd like to address in the .NET 5 time frame.

@runxc1
Copy link

@runxc1 runxc1 commented Dec 16, 2020

So I see this thread as I am attempting to update to .Net 5 and have a project that uses AspNetCore.NodeServices in order to run some javascript that used to be ran in the browser and need to get identical output and I'm seeing that there is a 5.0 preview released just 4 months ago. Are they looking at releasing it. As others mentioned I'd probably have to fork the code if it is abandoned.

@johnnyreilly
Copy link

@johnnyreilly johnnyreilly commented Dec 18, 2020

Hey all (and particularly @johnrom, @CodeTherapist and @danroth27)

I've just happened upon this issue. Yay! @johnrom suggested that UseProxyToSpaDevelopmentServer was not going away. It looks like it has: https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.builder.spaproxyingextensions.useproxytospadevelopmentserver?view=aspnetcore-3.0&viewFallbackFrom=aspnetcore-5.0

Like many others, I'm curious as to whether there is an alternative to UseProxyToSpaDevelopmentServer knocking around? As I understand it, that mechanism is simply a proxy and doesn't rely on implementation details around webpack etc and so hopefully doesn't conflict with the (understandable) reasons for deprecating NodeServices / SpaServices. This is ultimately just static file proxying which is a fairly generic need.

@CodeTherapist did a great write up on this and a workaround: https://codetherapist.com/blog/aspnetcore-deprecated-spa-services/

However, his solution was Vue specific; I was wondering if there was a more generic approach that is advised? Googling has not resolved this alas!

@johnnyreilly
Copy link

@johnnyreilly johnnyreilly commented Dec 18, 2020

So having just taken .NET 5 for a spin, it looks like Microsoft.AspNetCore.SpaServices.Extensions has UseProxyToSpaDevelopmentServer still in place. So ... great!

@alekkowalczyk
Copy link

@alekkowalczyk alekkowalczyk commented Dec 18, 2020

Since .NET 5 is out, how can we migrate out .NET Core 3.1 app to .NET 5 and keep the server side rendering of our React SPA? Does the app has to be split into 2 for front and back-end?

@MorleyDev
Copy link

@MorleyDev MorleyDev commented Dec 21, 2020

@alekkowalczyk You can switch to using the Jering.Javascript.NodeJS library to get this functionality for ssr.

@chamikasandamal
Copy link

@chamikasandamal chamikasandamal commented Dec 21, 2020

@alekkowalczyk You can switch to using the Jering.Javascript.NodeJS library to get this functionality for ssr.

@MorleyDev : Do you have any working samples to share here. that will help the community

benjimarshall added a commit to publichealthengland/ntbs_Beta that referenced this issue Feb 17, 2021
Remove aspnet webpack to make way for .NET 5 upgrade, and hot module
reloading of the site, which is much more difficult in .NET 5. See
this issue for a discussion of the .NET changes that lead to this
dotnet/aspnetcore#12890

Update webpack from verion 4 to 5. This required changing how GOV.UK
assets are made accessible, they are now included using the CopyPlugin.
benjimarshall added a commit to publichealthengland/ntbs_Beta that referenced this issue Feb 18, 2021
Remove aspnet webpack to make way for .NET 5 upgrade, and hot module
reloading of the site, which is much more difficult in .NET 5. See
this issue for a discussion of the .NET changes that lead to this
dotnet/aspnetcore#12890

Update webpack from verion 4 to 5. This required changing how GOV.UK
assets are made accessible, they are now included using the CopyPlugin.
benjimarshall added a commit to publichealthengland/ntbs_Beta that referenced this issue Feb 19, 2021
Remove aspnet webpack to make way for .NET 5 upgrade, and hot module
reloading of the site, which is much more difficult in .NET 5. See
this issue for a discussion of the .NET changes that lead to this
dotnet/aspnetcore#12890

Update webpack from verion 4 to 5. This required changing how GOV.UK
assets are made accessible, they are now included using the CopyPlugin.
@msftbot
Copy link
Contributor

@msftbot msftbot bot commented Feb 19, 2021

Thank you for contacting us. Due to a lack of activity on this discussion issue we're closing it in an effort to keep our backlog clean. If you believe there is a concern related to the ASP.NET Core framework, which hasn't been addressed yet, please file a new issue.

This issue will be locked after 30 more days of inactivity. If you still wish to discuss this subject after then, please create a new issue!

@msftbot msftbot bot closed this as completed Feb 19, 2021
@alekkowalczyk
Copy link

@alekkowalczyk alekkowalczyk commented Feb 19, 2021

@msftbot still no "proper" answer for in my opinion a very important question - How to properly do SSR in ASP.NET 5 using an SPA framework? Since it was functionality "out of the box" in ASP.NET Core 3.1 and older - a migration guide is in my opinion more than necessary.

@1kevgriff
Copy link

@1kevgriff 1kevgriff commented Feb 19, 2021

Might be worth keeping an eye on this issue: #27887

@Luiz-Monad
Copy link

@Luiz-Monad Luiz-Monad commented Feb 22, 2021

If you write F#, you can use https://fable.io/ to create isomorphic applications and share code between server and client.
This way you take backend code used for server-side rendering and compile it to JS and run inside node, instead of doing this hack of running node from aspnet core.
In some cases, you can run that and make it work barely enough to extract HTML and CSS from things like Material-UI.

@rjgotten
Copy link

@rjgotten rjgotten commented Feb 22, 2021

@Luiz-Monad

this hack

All the existing NodeServices does and is, is a thin layer of child process lifetime management and an HTTP loopback to facilitate communication.

The messy parts - and the only reason Microsoft could conceivably use as proper arguments to drop support - are in the JavaScript glue-code such as the aspnet-webpack NPM package, the state of which I've expounded on before. There's nothing wrong with the approach on principle and it is honestly quite architecturally sound.

I wouldn't exactly resort to calling a fairly standard and well-understood practice of inter-process communication over an HTTP loopback a 'hack' when compared to shoe-horning your entire application into an isomorphic rendering model that can fit yet another compiles-down-to-javascript cross-compiler. But maybe that's just me.

@Luiz-Monad
Copy link

@Luiz-Monad Luiz-Monad commented Feb 23, 2021

I wouldn't exactly resort to calling a fairly standard and well-understood practice of inter-process communication over an HTTP loopback a 'hack' when compared to shoe-horning your entire application into an isomorphic rendering model that can fit yet another compiles-down-to-javascript cross-compiler. But maybe that's just me.

That's not the part that was a hack, its totally valid to use HTTP to do IPC between two different processes, The hack-part was the way it was starting the node server from inside that library.
I would much prefer something I control directly from the infrastructure side, like in docker or something, than starting gratuitous process in my production environment.

@brunolau
Copy link

@brunolau brunolau commented Feb 23, 2021

For anyone needing mostly the UseWebpackDevMiddleware extension method - I've attempted to port the Microsoft.AspNetCore.SpaServices library into .NET 5 by using the https://github.com/JeringTech/Javascript.NodeJS library.

Migration path:

  1. Install the BrunoLau.SpaServices NuGet package
  2. Change using Microsoft.AspNetCore.SpaServices.Webpack; to using BrunoLau.SpaServices.Webpack;
  3. Change UseWebpackDevMiddleware to UseWebpackDevMiddlewareEx

That should do the trick...I've also attempted to port the Prerendering part, however as I've never used it and don't have time to learn just to test something I'll probably never use in production I haven't tested it

Source available on https://github.com/brunolau/BrunoLau.SpaServices

@rjgotten
Copy link

@rjgotten rjgotten commented Feb 24, 2021

@Luiz-Monad
The hack-part was the way it was starting the node server from inside that library.

Ah. If that's your beef, then iirc you can reconfigure the services collection with replacement classes that don't create a new node process and interface with it over local loopback, but which connect to an already running node process elsewhere.

Those parts should be replaceable as iirc one of the in-the-box replacements was to not use HTTP loopback but use named pipes.

@vslzl
Copy link

@vslzl vslzl commented Feb 24, 2021

Hello there, can anyone suggest a proper way to use ssr with recent versions of both asp.net and angular? for development I tried sth but for deployment it's not working at all. My old application was net core 3.1 with angular 11 works wit ssr but now I'm desperate...

@brunolau
Copy link

@brunolau brunolau commented Feb 24, 2021

@vslzl if you were using the Microsoft.AspNetCore.SpaServices library, you might try my port which is mentioned 2 comments above

@alekkowalczyk
Copy link

@alekkowalczyk alekkowalczyk commented Feb 24, 2021

@vslzl seems that the proper way is to split such app into ASP.NET back-end and node.js front-end for SSR, just wondering if there is an easy way to deploy such bundle into a single Azure AppService? 🤔

@vslzl
Copy link

@vslzl vslzl commented Feb 25, 2021

@vslzl if you were using the Microsoft.AspNetCore.SpaServices library, you might try my port which is mentioned 2 comments above

I'll try, thank you.

@vslzl seems that the proper way is to split such app into ASP.NET back-end and node.js front-end for SSR, just wondering if there is an easy way to deploy such bundle into a single Azure AppService? 🤔

Exactly, I don't want to split my application in two parts. Single Pain Application is enough. No need to double them.

@mopinsk
Copy link

@mopinsk mopinsk commented Feb 26, 2021

You can create directories within your Azure AppService and make them virtual applications.
I've created a directory 'webapi' which serves requests to the '/webapi' endpoint (ASP.Net Core Web API, .Net 5) and a 'client' directory for my Angular SSR client (Angular 11), which serves everything but 'webapi'.
For node.js in an Azure AppService you need to enable the iisnode module in your web.config (which you can find in the 'deploy a node.js app to azure AppService' tutorial.

@alekkowalczyk
Copy link

@alekkowalczyk alekkowalczyk commented Feb 26, 2021

You can create directories within your Azure AppService and make them virtual applications.
I've created a directory 'webapi' which serves requests to the '/webapi' endpoint (ASP.Net Core Web API, .Net 5) and a 'client' directory for my Angular SSR client (Angular 11), which serves everything but 'webapi'.
For node.js in an Azure AppService you need to enable the iisnode module in your web.config (which you can find in the 'deploy a node.js app to azure AppService' tutorial.

Interesting, how is it set-up in the dev environment? Is it within one csproj? How does the deployment look like, possible through a single "Publish" from Visual Studio?

@mopinsk
Copy link

@mopinsk mopinsk commented Feb 26, 2021

I don't have access to my development environment right now but I can give more information about my setup next week.
For publishing: I use Azure DevOps where I created a CI/CD pipeline that publishes whatever I have changed (either Angular Client or ASP.Net Core Web API, or both) to the AppService.

@mopinsk
Copy link

@mopinsk mopinsk commented Mar 7, 2021

You can create directories within your Azure AppService and make them virtual applications.
I've created a directory 'webapi' which serves requests to the '/webapi' endpoint (ASP.Net Core Web API, .Net 5) and a 'client' directory for my Angular SSR client (Angular 11), which serves everything but 'webapi'.
For node.js in an Azure AppService you need to enable the iisnode module in your web.config (which you can find in the 'deploy a node.js app to azure AppService' tutorial.

Interesting, how is it set-up in the dev environment? Is it within one csproj? How does the deployment look like, possible through a single "Publish" from Visual Studio?

I have finally had some time to create a repository and set up a little demo consisting of:

  • ASP.NET Core Web API (.NET 5)
  • Angular 11 Client with SSR (using Angular Universal w/ Express running in IIS/Azure by using iisnode)
  • GitHub Action to build and deploy to Azure Web App

You can find my repo here: https://github.com/mopinsk/aspnetcore-angular-ssr
If you have any questions, feel free to open an issue in the repo. Hope I could help.

@msftbot msftbot bot locked as resolved and limited conversation to collaborators Apr 6, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
breaking-change feature-spa
Projects
None yet
Development

No branches or pull requests