dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
34.59k stars 9.79k forks source link

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

Closed danroth27 closed 3 years ago

danroth27 commented 4 years ago

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:

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

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 commented 4 years ago

Is UseWebpackDevMiddleware going away with this change? Or UseSpaStaticFiles?

flcdrg commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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

CodeTherapist commented 4 years ago

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 commented 4 years ago

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

ericgreenmix commented 4 years ago

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

alexdresko commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

@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 commented 4 years ago

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 commented 4 years ago

@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 commented 4 years ago

@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 commented 4 years ago

@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 commented 4 years ago

@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 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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.

InvincibleDRT commented 4 years ago

@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?

We also use nodeservices to run puppeteer module on server side for PrintToPDF functionality. Spinning off as a community driven project is indeed a good idea

flcdrg commented 4 years ago

@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?

We use TypeScript/JavaScript to perform customer-specific data transformations together with a common .NET application.

We would be interested in taking on this as a community project (otherwise we'll probably end up forking/copying it privately)

atrauzzi commented 4 years ago

@danroth27 I might be missing something here, but there is no official react CLI for doing server side prerendering is there?

If I have a fully built JS bundle, it might be that only way to call it is to treat it like a JavaScript "DLL". That means there is no single convention that could reliably apply to it for a CLI tool.

I think it makes sense to continue offering an official way to call into JS from .net. Also, I wouldn't be surprised if losing this API surprised many more people than those chiming in here. It's about more than SPAs at the end of the day.

NotMyself commented 4 years ago

@danroth27 sounds reasonable to me. Seems like only my development workflow is changing. My deployment strategy should still work fine. So instead of having .net core proxy requests to my vue app, I can flip it over and have webpack proxy requests to the .net core app.

Might taking some fiddling to get F5 start-up and debug working the way I have it now, but that should be achievable. Let me know if you want someone to dog good a vue template.

danroth27 commented 4 years ago

I might be missing something here, but there is no official react CLI for doing server side prerendering is there?

@atrauzzi When we switched from providing our own infrastructure to using the CLI for Angular & React we made the decision that we would not try to provide our own infrastructure beyond what the CLIs supported. I may not be fully up to date on the latest features in create-react-app, but from their readme: "If you want to do server rendering with React and Node.js, check out Next.js or Razzle. Create React App is agnostic of the backend, and just produces static HTML/JS/CSS bundles."

danroth27 commented 4 years ago

We would be interested in taking on this as a community project (otherwise we'll probably end up forking/copying it privately)

@flcdrg That sounds great. And based on the responses here it sounds like there are some folks that also interested in the scenario and would probably be interested in helping out. Since we no longer plan to maintain this code ourselves, I expect that turning the NodeServices (and maybe also the webpack middleware functionality if folks are interested) into a community based project will involve copying the code into a new community maintained repo and updating the namespaces and package IDs accordingly. I'm sure the .NET Foundation would be happy to work with you to help make this community project successful. If you'd like to discuss in greater detail what that might entail we can discuss offline.

flcdrg commented 4 years ago

@danroth27 Sounds great. I'll drop you an email to follow-up.

David

Get Outlook for iOShttps://aka.ms/o0ukef


From: Daniel Roth notifications@github.com Sent: Thursday, August 8, 2019 4:11 am To: aspnet/AspNetCore Cc: David Gardiner; Mention Subject: Re: [aspnet/AspNetCore] [Announcement] Obsoleting Microsoft.AspNetCore.SpaServices and Microsoft.AspNetCore.NodeServices (#12890)

We would be interested in taking on this as a community project (otherwise we'll probably end up forking/copying it privately)

@flcdrghttps://github.com/flcdrg That sounds great. And based on the responses here it sounds like there are some folks that also interested in the scenario and would probably be interested in helping out. Since we no longer plan to maintain this code ourselves, I expect that turning the NodeServices (and maybe also the webpack middleware functionality if folks are interested) into a community based project will involve copying the code into a new community maintained repo and updating the namespaces and package IDs accordingly. I'm sure the .NET Foundation would be happy to work with you to help make this community project successful. If you'd like to discuss in greater detail what that might entail we can discuss offline.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://github.com/aspnet/AspNetCore/issues/12890?email_source=notifications&email_token=AAC5522YUSBRXP2D6UOYJKDQDMJPBA5CNFSM4IJOXOR2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD3ZK24I#issuecomment-519220593, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AAC5526LTNBPY7DBUBT5RVLQDMJPBANCNFSM4IJOXORQ.

flcdrg commented 4 years ago

Apologies, but due to changing circumstances we aren't able to take over Microsoft.AspNetCore.NodeServices, so extending an invitation to others who might be interested in taking it on.

atrauzzi commented 4 years ago

@danroth27 I wouldn't base this decision around create react app as there are an infinite number of ways for runnable react code to be produced. Any new functionality being made has to work with bundled code, not passing through to a single external CLI.

Moreover, the nodejs services imply much more than just server side rendering. So I feel like there's more at stake here. Scoping this to only SSR risks missing people who are using it to execute JS code for other purposes.

ashleynolan commented 4 years ago

Just to add how we use the NodeServices package – we use it to provide SSR when rendering Vue components. Without this, the only way to provide SSR for our application would be to switch the application over to using Nuxt with Node to serve the front-end (vue-cli doesn't provide SSR, so a plugin to use this wouldn't be a way to migrate. We would have to rewrite our application to use Nuxt).

This would be similar with React (as far as I understand it). The only way to do SSR would be to either statically generate your templates (via something like create-react-app) or use Next.js with Node to serve the front-end. Again, this is a pretty big migration path from using .NET with Node Services.

raphaelr commented 4 years ago

Regarding WebpackDevMiddleware:

I managed to replace this with UseReactDevelopmentServer fairly easily (even though my project doesn't even use React!). The good thing about UseReactDevServer is that it automatically runs the NPM script for you and figures out a port to use. As far as I can see the only React-Ism in that middleware is that it expects the text "Starting the development server" in the server output (https://github.com/aspnet/AspNetCore/blob/2e0cf080dffa957fa0a665da5ec87d2be1b402ee/src/Middleware/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddleware.cs#L88).

It'd be nice if there'd be a general UseDevelopmentServer that doesn't depend on that string. Again, the NPM script starting and the port detection are really useful for development.

It's undocumented, but I made this little express server that works for me as a WebpackDevMiddleware replacement: https://gitlab.com/raphaelr/clientapp-spaservices-extensions/blob/master/Test.SpaServicesExtensions/ClientApp/dev-server-for-aspnet.js

atrauzzi commented 4 years ago

I think we're getting carried away here.

One part of the original functionality (NodeServices) takes a .js file, loads it and allows you to make calls into the resultant scope -- and to capture returns in C# space. Webpack, or any CLI seems unrelated.

.net code shouldn't need to think at the level of webpack or any specifically targeted command line utility. It should only be thinking about .js files that are built by something from the outside as a resource/asset.

Basically: Run the toolchains some other way before the .net code runs. So long as it outputs a .js file, then .net is in a better position to make general assumptions about what to call. Integrating with CLI tools really mixes concerns.

Simon-Bull commented 4 years ago

@danroth27 Is there going to be a migration path for applications that execute javascript at run-time? In our environment, we use a large amount of .NET Core / Standard middleware and libraries that integrate easily with our hosting environment, monitoring stack etc. We can then use VueJS components in both SSR and browser, and with the benefits of running our backend on .NET Core.

Dropping NodeServices without an alternative would most likely cause us to move away from .NET Core for our VueJS applications, and involve significant work for us.

Sebazzz commented 4 years ago

Please provide a migration path for Webpack. Deprecation is fine, as long as there is a clear migration path.

jhaygood86 commented 4 years ago

+1 on the replacement for Webpack. We use AngularJS (1.7, not the new Typescript stuff) in a webapp that originally was .NET Framework 4.6.1 but now fully on .NET Core 2.2 with UseWebpack. We were able to get rid of a whole bunch of custom code and dramatically increase developer productivity, and this would suck having to go back to the old way....

LyleDavis commented 4 years ago

What is the recommended way forward for those projects that consume node libraries using dotnet services?

As an example, a project I'm working on has a load of calculations written in javascript (executed client and server side) and nodeservices invokeasync is used to run these server-side. Is the recommended way forward to write these services in node instead?

It would be a shame if so, we much prefer .net ecosystem - it's just that we have specific requirements with regard to running js modules common with other parts of the system.

dasMulli commented 4 years ago

I have also been using INodeServices directly heavily to run javascript programs, e.g. for generating PDFs using JS libraries.

Could this be moved to Microsoft.Extensions?

Node services was advertised (READMEs, might need to google for blog posts) as an abstraction over Node and running JavaScript for any type of application (web, service, console, ...), with SPA integrations being one of the consumers.

It would be a loss and a then missing feature to use node services. Is there a recommended migration path for INodeServices?

LyleDavis commented 4 years ago

Providing NodeServices as a generic way to into JS from .NET Core is not something we want to maintain long term.

@danroth27 Is this a new decision?

I agree with @dasMulli that https://github.com/aspnet/AspNetCore/blob/master/src/Middleware/NodeServices/README.md#microsoftaspnetcorenodeservices definitely implied it would be an officially supported generic abstraction layer - and a pretty useful one at that.

If it is not a new decision, please can someone who knows the internal technical roadmap have a quick look over other READMEs? It feels like if something is an implementation detail and not a long-term public API then that should be pointed out before we start relying on it in prod environments.

If this is being moved over to a community project I'd love to get involved, but I'm very new to .net and will need someone fairly experienced to lead.

Also, please could you update the labels on this issue to include breaking change?

davemanton commented 4 years ago

I haven't been able to find any resources to server side render react or other javascript frameworks on .net core without using these prerendering services.

It seems that by making this obsolete this means .net core is not a sensible choice for any form of web app which involves SSR.

Is there a documented alternative way to achieve SSR of javascript?

petvas commented 4 years ago

create-react-app is not a react standard CLI just a boilerplate and nothing to do with SSR. Without NodeServices SSR is not possible (in the efficient way)

Example: we have a simple product page for an e-commerce website.

Client side render:

Server side render:

No matter what library we are using for SSR next.js or anything. Somehow that SSR process needs to get the data.

ps.: sorry for my English, I hope it was clear enough, feel free to ask if something is not make any sense.

ChristopherHaws commented 4 years ago

@danroth27

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?

We are using NodeServices to run our webpack build which doesn't seem possible with the SpaServices.Extensions. We are also using NodeServices to generate email templates using razor to generate mjml and running it through mjml via NodeServices.

msivri commented 4 years ago

@danroth27
According to the docs on MSDN, Microsoft.AspNetCore.SpaServices.Extensions prerendering relies on aspnet-prerendering npm package. Am I missing something? Will there be an alternative NPM package to facilitate prerendering?

The way I understood it is that NodeServices nuget will become obsolete but the functionality in Microsoft.AspNetCore.SpaServices.Extensions will remain so that pre-rendering can be taken advantage of. However, I don't understand how this is achieved without aspnet-prerendering npm package and can't find documentation about it.

danroth27 commented 4 years ago

Thanks everyone who shared details on their usage scenarios for NodeServices. We understand that this library along with the functionality in SpaServices is fulfilling a need for some users. This functionality shipped with .NET Core 2.1, which is a Long Term Support (LTS) release, and will continue to be supported for the support lifetime of that release. The functionality will also ship in an obsoleted form as part of .NET Core 3.1, also an LTS release, with the intent to remove it in .NET 5. For folks seeking to continue to use this functionality after that time period the code is open source and available for anyone to use and maintain as they see fit. We would also happily support anyone from the community who is interested in taking this code and maintaining it as an independent project.

LyleDavis commented 4 years ago

@danroth27 Fair enough, deprecation is necessary sometimes for a long-term goal.

I recognise that microsoft might not want to provide an official way for this sort of thing, but is there any advice on what to do for those of us who do have to run javascript on the server-side for application functionality? We'd prefer not to, but it's a necessity for us.

Is using INodeServices at runtime in this way recommended, or would we be better off looking at some sort of RPC communication between processes, or even just rewriting those services in Node? It would be great to have some advice on the best way to achieve server-side js in the .net ecosystem.

danroth27 commented 4 years ago

@LyleDavis As far as I know there's nothing technically wrong with approach taken by NodeServices for calling JavaScript from .NET at runtime. The issues with maintaining this code are related to keeping it up to date with the latest Node releases.

alexdresko commented 4 years ago

The issues with maintaining this code are related to keeping it up to date with the latest Node releases.

That's the most helpful comment so far, I believe.

a-stankevich commented 4 years ago

We would also happily support anyone from the community who is interested in taking this code and maintaining it as an independent project.

This actually sounds like a good option. You've done really great job creating and maintaining it so far. Having a node process being managed by asp.net application is a huge relieve for developers. Now at this point the community around it seems to be mature enough to be able to maintain it. Speaking of that, what would be the recommended process of doing so? Is it just about taking current source code and publishing it under a different name?

poke commented 4 years ago

@a-stankevich:

Is it just about taking current source code and publishing it under a different name?

You could probably run a git filter-branch to extract the original history of that code. That way, you are automatically including proper attribution for the original work.

danroth27 commented 4 years ago

Now at this point the community around it seems to be mature enough to be able to maintain it. Speaking of that, what would be the recommended process of doing so? Is it just about taking current source code and publishing it under a different name?

@a-stankevich Yes, we would recommend moving the code to a new repo, and renaming the packages and namespaces to remove the "Microsoft" branding. Since the code is already owned by the .NET Foundation we would also be happy to help get the project setup as a new .NET Foundation project.

If anyone is interested in taking this on please feel free to reach out to me and we can discuss in further detail setting this up as a community project.

alexdresko commented 4 years ago

@danroth27

If anyone is interested in taking this on please feel free to reach out to me and we can discuss in further detail setting this up as a community project.

What are the requirements?

danroth27 commented 4 years ago

What are the requirements?

@alexdresko None really other than a strong desire to contribute to the .NET community and ecosystem. The code is open source and freely available so anyone can do with it what they want.