I've developed a web application using React and Redux and then packed it with Webpack, it's hosted using IIS and presumably just runs client-side and makes calls to a Web API (.net for reasons); also hosted on IIS.
How do I make the jump and make this application 'isomorphic' so that the React code runs both client and server side?
You'll need a few things:
1) some way to run node: Really the only things that happen server-side with React are a renderToString call to give you strinigfied HTML you can send to clients (it's just a static HTML rendering of your app w/ React), hydration (see more on that in a bit) to get data into your components, and route-matching.
2) a router (if you have routes): If your app uses multiple routes, you'll need to use React-router to tell node what component(s) should be rendered
3) a good reason to go universal: there are some relatively simple aspects to going universal and there are some relatively complicated ones. Matching the routes isn't all that hard, and it will essentially just be you telling your server what to send down. The harder, more complicated part of universal JS w/ React is fetching data to send down to clients on initial render. This usually involves some server-side data fetching, so you have to have a way to both get the data and pass it into your app to be rendered correctly. There are ways to do this, but it is certainly a significant step up in terms of overall complexity.
This is how I did it, w/o the need for any server-side data fetching: Server side rendering with react, react-router, and express
See also:
https://ifelse.io/2015/08/27/server-side-rendering-with-react-and-react-router/
http://jamesknelson.com/universal-react-youre-doing-it-wrong/
You need Node.js to make an isomorphic web app.
This is because an isomorphic application requires an appropriate server-side runtime to execute the React Javascript code on the server. I don't believe IIS has support for parsing Javascript exactly - only Node has this runtime.
If you aren't using Node, then you should introduce it at some stage in your application. You can use IIS as a reverse proxy: create a Node server for IIS to forward requests to, let Node render the React as static HTML using renderString, and then have Node respond to requests from IIS with the rendered HTML. IIS will act as middleman for all incoming requests and responses.
Reverse proxies add some minor latency to an application, but, as always, premature optimisation is the root of all evil.
Related
I have been using SvelteKit casually for a little bit now in my own personal projects. I have used other frameworks like Next.js and Nuxt.js in the past too. It has always confused me when working in these frameworks where the code I am writing is actually run.
For some context in my day job I use the ASP.NET Core platform to create more traditional web applications.
In ASP.NET it is clear to me where the code I write is run. I write frontend markup in Razor pages (just a way to write html but inject C# expressions inside). When the browser requests a page to view from the server, the server grabs the page and any data it needs, generates html from the Razor page markup and sends it back to the browser to render it into a beautiful web page 😁 Also within the same application I can write http handlers that can listen out for form submissions and interact with a database via an ORM.
In JavaScript frameworks such as SvelteKit, Next.js or Nuxt.js however this process has always confused me. I know that each of the frameworks use their respective component frameworks (Svelte, React and Vue) under the hood in some way. I also understand that each framework adds the ability to have file based routing so that files in a specific place in the src code map to a specific route in the browser. e.g. in SvelteKit you can have a svelte file at src/routes/myAmazingPage.svelte that gets rendered in when the browser browses to https://wherevertheappishosted.com/myAmazingPage.
However this is where my understanding becomes a bit clouded. When you browse between pages in SvelteKit it does not cause page reloads in the browser. This tells me that the framework is using some kind of client side routing to handle this behavior as the url at the top of the page and the page contents change without causing a page reload. There are also no network requests being sent to the server to fetch pages at a certain url which tells me that all the data fetching must be being done in JavaScript on component mount or within some other lifecycle hook.
So my question is in that case if there are no http requests being sent out per page request (i.e. when you navigate to a different page) to a server, then where is the code I write in SvelteKit actually run? Is it the case of all the code I write in SvelteKit is compiled and sent over to the browser on initial page load and then all run in the browser? Including code I write to fetch data within lifecycle methods like onMount().
Also if that is true then do these frameworks have any kind of http server running in the background to handle any other web requests? For example can I write a http handler in svelte kit to handle a post request from a form submission to save data to a database? That is the way I would go about handling form submissions in ASP.NET and I have always wondered if it is possible to do in SvelteKit, Next.js or Nuxt.js. The only alternative to this that I have used in the past is writing a separate http server written in node.js and express to handle communicating with a database and other operations, that I send all my requests from my SvelteKit apps towards.
May be a bit of an obvious question to more experienced JavaScript framework developers out there, but since working in a more traditional MVC framework like ASP.NET on a daily basis this subject has always confused me.
SvelteKit applications can be deployed few different ways to production.
In development mode, the request handler is run by Vite development server
In static production deployment mode, there is no request handler and nothing is run on the backend - the visitor just downloads HTML, CSS and JS files from the server
In server-side rendering (SSR) production mode, the requests are run by SvelteKit node adapter (Node.js process). The adapter allows also to write server-side request handlers that are not available in the static deployment mode.
Next.js and Nuxt.js have their respective own web servers written in JavaScript on the top of Node.js V8 virtual machine.
I'm trying to upgrade an old mobile application written in vanilla Javascript+React hosted on Cordova. This application leverages a simple api on the server-side:
when the app requires a page, sends a request to the server
the server elaborate the request, fetch the resources, and then reply with a complete HTML+JS. The Javascript is a ReactJs view compiled with Gulp/Browserify
the app takes the reply and stores it in a local Sqlite DB, then mount the received code and the view become reactive.
if the user requests a view but has no connectivity, the app search though the Sqlite db wether there is a cached view and uses it instead of requesting a fresh copy from the server.
When developing, the React JSX code is immediately compiled to a vanilla JS so, when in production, the api only needs to merge the vanilla JS with the HTML template. Plus, adding new features and fixing bugs is quite easy, because each user essentially download any updated view, each time he enters in it.
The problems with this approach are:
developing is painful because of the continuous compilation
a "base" part of the application resides on Cordova assets (basically the utilities to fetch from server, caching etc) and fixing this parts needs a new app release or ugly override patches
the caching feature often causes problems to the Sqlite database (which is used also for other stuff on the app); as a result, the DB sometimes corrupts and the user must clear the app data.
we would like to get rid of React
We already used NuxtJs for generating static sites, and it's great, but in this case I cannot leverage the SSG because the app should be almost completely served from the api, so we can keep the easy-feature-and-fix stuff.
I never used NustJs SSR and wonder if could be suitable for my use case, for example, could I spin up a NuxtJs instance on server-side which generates the html output and hydrate a barely empty Javascript client on Cordova? Is there a better way to accomplish this task? Should I use only Vue instead?
Thanks
Are server-rendered frameworks/libraries (such as Nextjs for React, Nuxt for Vue) and non-JS REST API backends (i.e. Java, Django, Go etc.) mutually exclusive or can they be used alongside?
Specifically, I am using Go for building a REST API at the backend and I wonder if I have to give it up for having the pages server-rendered.
It's encouraged to use a separate API server with next.js even if you're using JavaScript for both. It's common to have the api on api.example.com, and to have the next.js app talk to it whether it's doing server-side or browser rendering.
If you want to have them on the same domain so you can cookies directly, you can use path aliases in now.sh, a Heroku-like PaaS from Zeit, the developers of Next.js. These can be set up in development with now-server. This can also be done with reverse proxies in nginx, apache, netlify, and CloudFront, or using path-based routing in AWS's Application Load Balancer.
These are two different concerns, really: Vue and React are JavaScript frameworks. They wouldn't run on your Go-based server application.
There's nothing to stop you from rendering HTML in a Go application, but a Go server is not going to run a JavaScript framework. If it did, it would likely require extra scaffolding, and at that point you might as well set up a NodeJS server to handle rendering those routes.
I'm trying to learn React JS, but I have difficulties understanding how it should work with NodeJS, let's say with Express.
So far I understand that ReactJS is "V" in "MVC"
This is easy, I can already write a code using create-react-app
This is how I understand that:
"natural" way of combining React and Express is to simply write frontend in React and api in Express (with Mongo for example).
This way we can simply make ajax calls from React to our /api and show data
there is also a possibility to use React to server side rendering, which requires little more configuration. This way we do not call /api from React, we just use React to write code which can be rendered by Express
My question is Am I thinking right ?
Not sure about all that...
Is Isomorphic JavaScript somehow related to #2 ?
You are mostly correct, but using server side rendering does not mean you do not also issue api requests ever. Server side rendering is a technique used to improve initial load time. Rather than pulling down your javascript bundle, which then makes some api calls to load a bunch of data it needs to render, you instead do that initial rendering and bootstrapping of the app on the server. The resulting html and initial state of the application are then returned to the client so the app can be shown immediately to the user. So when talking about server side rendering with react, it's really about the initial load.
After the initoal load, you still have a dynamic frontend applicatoon. You still end up making api requests as the user interacts woth the app. If I go to a different route in the app (assuming it's a single page app) which requires additional data, I'll still be issuing a GET request to load that data. If I click a button to update a resource, I'll still be issuing a PUT or PATCH request to do so.
So in terms of the question of how express and react fit together, express (or whatever backend language/framework you use) provides the api to interact with data in your data store. And react is allowing you to build views that consume those apis. Server side rendering is just an additional technique you can use, not a totally separate paradigm.
So I am creating a multiplatform application using React & Spring (Java)
I want to make the Spring backend a REST webservice that can be called by both a React-Native and a React frontend.
I currently have my project broken up into 3 sub projects: backend (Spring), webapp-frontend (React webapp), mobile-frontend (React native)
My question is on how I should actually serve the React webapp frontend. I will have the webservice on a server somewhere so that the React code can hit it to make API calls, but as far as serving the React webapp would it be better to do serve it with the same backend server or would it be better to make a seperate frontend server with something like express? Also, are there any other alternatives?
Serving the react webapp with either express or the same server as the REST backend is both valid options. I would say that if there is no specific reason for choosing express, serving it on the same server as the spring backend is your best choice.
Recall that the frontend and backend will still be decoupled and only communicate through the REST-interface so to extend the backend-server to host the react-webapp should be quite simple, here's an example that could be helful: React,Spring,Rest example
However there is a couple arguments that I see that could make you choose a separate server then the REST backend, for example:
Isolated restarts and failures. If you want to be able to restart only your react-frontend without affecting the REST backend you will probably want to run them on different servers. Another thing to consider is if you expect that the backend will need to scale heavily and you'll need to replicate the backend across multiple servers, that might be easier to do if the frontend is running on its own separate server.
Server-side rendering of JavaScript (React) is possible through a node.js server like express but I don't think it is possible with a Spring server.
Also, are there any other alternatives?
Other alternatives then express/Spring, Yes. Other alternatives then hosting the fronted on the backend-server or on its own server? No
There are pros and cons with both choices and what is best depends on your needs.