What is the benefit of serving react app(front end) from express app(back end) - node.js

I have developed and hosted few react applications but I'm still confused about the word server side rendering. So, I'm curious to know what is the benefit of serving my react applications from an express server.
Thank you as I look forward to your response.

Please consider clarifying your question, because I don't know also if you use next.js or nuxt.js.
Angular, React, Vue.js are JavaScript frontend frameworks/libraries, which means they are using JavaScript language.
The websites on the Internet contain HTML, CSS, JavaScript Vanilla code.
The application you developed using React.js needs to use React.js library source code, and then you need the React.js code to be compiled to JavaScript Vanilla code because the browser at the end needs a JavaScript native code that it can read.
When I need to see your hosted website, I need to write the domain name to see it, so the HTTP request at the end goes to the server which is hosting your react app, thus if your react application contains just a static content, for example, a landing HTML page, then there is no need for server-side rendering from Express(Node.js), Ruby, PHP, Java,...
What I mean by static content is content that doesn’t change in response to different users, all of them will get the same content.
Notice you can host a static website in Github and you still don't need any server-side rendering...
Let's have a small application for a better explanation:
If you developed a Portfolio that contains a description of yourself, images of your projects, skills, then here there is no need for a server-side rendering.
But if you developed a system that lets a user who has permission to create a short link from a full URL, then you need a backend server(like Java, Ruby, C#, PHP,...) to host the logic code in order to generate a tiny URL from the full URL, and then save it in a Database, that way any user can click the generated tiny URL then this request goes to your backend server which needs to redirect the user with correct full URL, an application like this cannot be done using React.js alone, you need a server to handle the logic.
Returning to your answering your question: "So, I'm curious to know what is the benefit of serving my react applications from an express server."
If you have static content you can avoid using Express, but if you think your application needs some backend logic in the future, then Express or any other backend framework will help you in that.
*Notice when you have a static website, and you tried to edit the content of it, the users which already visited your website, their browser might cached your website content unless (they disabled this option in their browser), so if your website is cached in users' browsers they might not get the updated content unless you changed the static website file name for example by adding ?092130123 to file name in order to let the users' browser download the updated data

Related

Why does backend development need a seperate server?

I am developing my own website. So far, I've used React for the frontend and Flask for the backend. I've been doing frontend development for a while now but I'm just starting to get into the backend.
From my limited understanding, frameworks like Flask and ExpressJS create their own servers and host data that the frontend can use. It seems to me that that they automatically create websites to host and receive data. In my website, I route the backend to do what I want and use fetch requests with POST and GET from the frontend to communicate.
Although it works, to me, it seems overly complex. Why does the backend need it's own server? It seems unnecessary to create a proxy for the frontend and fetch data. Why can a website not just run custom code in the background, why does it need a service like Flask or ExpressJS to run in the background for it? These backend frameworks run Python or NodeJS in the background, but wouldn't it be much simpler if the website itself could run Python or NodeJS in the background?
I also see that in frameworks like React, you can import things and use modules— like in NodeJS. While importing some modules works, the require keyword is not allowed and normal NodeJS code will not work. Therefore, the backend will not work. Why is this— why can't you just run backend code natively? Instead you have to go through fetch and specify headers to basically translate information from your frontend to your backend.
Forgive my amateur understanding of web development, but the frontend/backend system seems overly complex to me. Thanks in advance.
Why does the backend need it's own server?
Where will the client store data so that when you open the page again the data will still be there? You can use localStorage but this is locked to that particular browser. What if someone logs in on a different device or uses a different browser?
Where will the client get the application from in the first place? Your application needs to be packaged up in a form that can be easily downloaded, and it needs an address to be loaded from. This is all considered "back end" even if you're using a static hosting service like GitHub Pages.
There's a lot of reasons why a back-end exists and needs its own server. Any application with persistent state which is expected to work across different sessions needs at least one of these.

Recommended practices when developing full-stack applications based on Node.js and AWS

I've been working on the front-end so far, now I'm going to create my first full-stack application. I want to use node.js, express and AWS for this.
At the design stage, I already encountered a few problems. Therefore, I have a few questions and I am asking you for help:
Can I send a message (simple JSON or database value) from the server to all clients who have already opened my home page in a simple and cheap way?
I'm not talking about logged in users, but all who downloaded the main page (GET, '/')?
Using the admin panel ('www.xxxxxxxxx/admin'), I want to send a message to the server once a day. Then I want to change the HTML to display this message. I was thinking to use EJS for this and download this message from the database.
Can I make it better? If someone visits my home page (GET, '/'), EJS will download the message from the database each time! Even though its value is the same for 24 hours. Can I get the value once and then use it until the value is changed? How to store the message? As a JSON on the server? Or maybe in the .env file?
If the user refreshes the page, do I have to pay for calling all AWS functions to build the page each time? Even if nothing has changed in the files?
How to check if the page has new content and then send it to the user, instead of sending the unchanged page files: .html, .js, .css, etc.?
Can I send the user only the changed, dynamically created html file, and not send again unchanged .js and .css files?
Does every user who opens the home page (GET, '/') create a new connection to the server using WebSocket / socket.io?
I will try to answer some of your questions:
Can I send a message (simple JSON or database value) from the server to all clients who have already opened my home page in a simple
and cheap way? I'm not talking about logged in users, but all who
downloaded the main page (GET, '/')?
I guess you mean sending push notifications from the server to the user. This can be done with different services depending on what are you trying to build.
If you are planning to use GraphQL, you already have GraphQL subscriptions out of the box. If you are using AWS, go for Appsync, which is the AWS service for GraphQL.
If you are using REST and a WebApp (not a mobile app), go for AWS IoT using lambdas. Here is a good resource using Serverless Framework (API Gateway + lambdas + IoT) for unauthenticated users: https://www.serverless.com/blog/serverless-notifications-on-aws
If you are planning to use notifications on a mobile app, you can go for SNS, the "de facto" service for push notifications in AWS world.
Using the admin panel ('www.xxxxxxxxx/admin'), I want to send a message to the server once a day. Then I want to change the HTML to display this message. I was thinking to use EJS for this and download this message from the database. Can I make it better? If someone visits my home page (GET, '/'), EJS will download the message from the database each time! Even though its value is the same for 24 hours. Can I get the value once and then use it until the value is changed? How to store the message? As a JSON on the server? Or maybe in the .env file?
Yes, this is the way it's expected to work. The HTML is changed dynamically using frontend code in Javascript; which makes calls (using axios for example) to the backend every time you get into, i.e. "/" path. You can store this data in frontend variables, or even use state management in the frontend using REDUX, VUEX, etc. Remember the frontend code will always run in the browser of your users, not on your servers!
If the user refreshes the page, do I have to pay for calling all AWS functions to build the page each time? Even if nothing has changed in the files?
What you can do is store all your HTML, CSS, Javascript in an S3 bucket and serve from there (this is super cheap, even free till a certain limit). If you want to use Server Side Rendering (SSR), then yes, you'll need to serve your users every time they make a GET request for example. If you use lambda, the first million request per month are free. If you have an EC2 instance to serve your content, then a t2.micro is also free. If you need more than that, you'll need to pay.
How to check if the page has new content and then send it to the user, instead of sending the unchanged page files: .html, .js, .css, etc.?
I think you need to understand how JS (or frameworks like React, Vue or Angular) do this. Basically you download the js code on the client, and the js makes all the functionality to update backend and frontend accordingly. In order to connect frontend with backend, use Axios for example.
Can I send the user only the changed, dynamically created html file, and not send again unchanged .js and .css files?
See answer above. Use frameworks like React or Vue, will help you a lot.
Does every user who opens the home page (GET, '/') create a new connection to the server using WebSocket / socket.io?
Depends on what you code. But by default what happens is the user will make a new GET request everytime he accesses your domain, and that's it. (It's not establishing any connection if you don't tell the code to do so).
Hope this helps!! Happy coding!

How do you manage repositories for production/deployment of Node-React app?

Not long ago , we used to have server render pages and then React came for client side rendering and single page application.It introduced virtual DOM's and changed the way we write our code.
We require all these react libraries and install them as dependencies before writing our codes. Now we can break into many components , have many css and scss files including images. But at the end we will build the files, make compact bundle and serve from build folder.
Express get route
app.get('*', (req,res) =>{
res.sendFile(path.join(__dirname+'/client/build/index.html'));
});
Heres, What I have understood :
Build folder is the place where webpack combines all the files and create minified bundle ready for deployment. That file is basically simple HTML and JS files which every browser can understand. As all the browser doesn't understand ES6 and much more, we have to convert all these files into plain language that every browser can understand.
Also, webpack-dev server is only for development purposes and we won't be running it into production.
Is virtual DOM/Real DOM just for development purposes? or
are those react libraries also trans-piled while building the minified files? If later is the case , react is run on background mode on client's browser? I want to know how react takes care of client side routing after the building the app.
How do you manage github repositories for Node-React app? Do you keep two different repositories one for front end and other for back-end? Whats the industry standard?
If you keep two repository, how do you deploy the front-end code? As you can't run the webpack-dev-server into production. Nor you can specify the public static (build folder) in your back-end(express server) as they are separated in two repos. How does, either the integration of these two repositories take place( lets say we have two AWS EC2 instance, one for each) or front-end get served from the front-end repo??). Can you actually use something like npm serve in production ??
what am I trying to do ?
I want to deploy my node-react app on AWS. I have only one repository on github. I have one folder "client" inside my repo where all the react code sits with its package.json file. All the other files for server are inside root folder (server doesn't have its own folder and files are scattered inside root folder). So there are two package.json files, one inside root folder for server and one inside client folder.I am planning to run my-node app on a docker container.
Please help me understand the core concepts and standard practices for code hosting and deployment keeping large scale enterprise application in picture.
I would not go into explaining all the points in your question here because, #Arnav Yagnik and #PrivateOmega have both done a brilliant job at explaining most of them. I would definitely recommend you to read their answers properly and read the links provided for more information before reading this answer.
I would like to address your question of deploying a Node-React application. In production, generally, we have different deployments (or "repositories" as you mention in your question) for both the front-end (React) and back-end (Node). This allows your back-end to sit in an EC2 instance, for example, with auto-scaling to make sure that it can cope up with all the requests coming in.
As mentioned in the previous answers, and in your question as well, webpack compiles and minifies the React files into simple HTML and JS files, which most browsers can run (I'm not going to explain VirtualDOM here because it has already been perfectly explained in other answers). You would then take these minified files and serve them from an S3 bucket for example, because again, it is a single page application (also discussed in the other answers) and the business logic is already in the minified JS files and its just simply sending all requests to your back-end server.
Now for front-end, you can use TravisCI for example to deploy the build folder (the one you talk about in your question) to an EC2 instance and serve your files using NGINX or if you can configure a CDN deployment properly, you can serve the files from an S3 bucket for the most optimal performance.
You can think of serving the React application like sending a cryptic block of code to your user's browser. Now you can deploy this cryptic block of code to a publicly available S3 bucket, and serve it from there. Again, because of webpack and minification/uglification, no on would be able to make any proper sense of what your original code was, remember that you can still access all the code in Chrome's Sources tabs for example.
I would like to address this with different approach.
Server Rendered Pages : The concept has not changed, server when encountered with a DOC request it has to respond with a html. Now HTML may or may not contain scripts(can be either inline or a external server address). In case of question's context you can still ship HTML where it will download scripts that you have written(may include react or not). for most cases you can ship empty html with scripts tags which will download the scripts over network and execute them which would contain all the rendering logic.
To Answer your questions :
1st : There is no background mode in a single threaded JS(unless we want to talk about workers but we can leave them out for this discussion). By writing in code you are not interacting with any DOM. You are instructing your components(extended by React) when to change their state and when to re-render(setState). React internally calculates the virtual DOM and compare to Real DOM to calculate actual changes that are to be made on Real DOM(this is very abstract answer, to get more understanding please read react docs, Baseline here is you are not interacting with any DOM just instructing React core library when to update and what is the updated state)
2nd : If you want to support SSR(server rendered pages). I would suggest to make 2 folders , client(this would include all client components and logic) and server(would include all server side logic) with different package.json as packages differ for both applications.There is no such industry standard here, what floats your boat should work but generally making directories based on logical entities should satisfy separation and maintainability, if in future you think you want to fork out server and client in separate repos , it would definitely make the process easy.
3rd : You shun running webpack-dev-server in production. Files are generally not obfuscated hence payload is heavy(not to forget your written code is out there). Even if you want to make different repos, server can spit out html and html can request scripts with your client server.
How to deploy : Deploy your code and run :
node server/app.js
and in app.js you can write the location block what you have mentioned.
P.S. : If you just need a server with that location block. do you really need a express server? You can upload the client build to a CDN and route your domain to serve index.html from the CDN(s3 bucket can also be used here)
I would like to start off with clearing up the terminologies as much as I can.
Like you said server rendered pages was a more prominent standard in the past, but it hasn't changed at all with the introduction of React, because even React has the support for Server rendering or SSR, which means HTML pages are generated at server side and then served to clients using browser.
And client side rendering means, a HTML page is loaded to browser and then javascript code renders things on top of those HTML pages and make them interactive.
And single page application concept is that we have only a single HTML file or base HTML page on top of which based on user interactions and data from server it is rewritten continuously.
Virtual Dom is an amazing concept introduced by React. React library code recreates the structure of all elements(called DOM elements) of a HTML page in the memory in a tree form. This enables React algorithm called Fiber to reconcile appropriate changes as per route update or any other changes first on this tree like structure before translating them onto the real elements in the HTML page.
Babel is a transpiler to transpile latest features that browser engines haven't started supporting to code that they can understand, usually ES6+ code into pre-ES6 because all browser supports that. In React application, if you have written application using JSX syntax, babel supports transforming JSX into normal javascript also.
Yes, breaking up of pages into many components is possible due to compositional nature of components by React which means we can build complex things by combining small and more focussed things.
At the end before serving it to end users, we can't have web application lag due to the huge size of code, so during the build process, things like minifying(removing whitespace etc) and other optimization like combining multiple javascript files into one etc are done, and then compact bundle is served from build folder like you said.
Yes, build folder is where webpack does the minifcation and combination to create a bundle as small as possible. It is basic HTML and JS files that is understood by every browser, and if the code contains something that a particular browser doesn't support, appropriate support code or something called polyfill is also bundled with it. Technically you can't say browsers only understand pre-ES6 code because a lot of browser engines have implemented plenty of ES6 features already.
Webpack dev server is just used to serve a webpack application over a port like a node.js server and gives us features like live-reloading which is needed when you constantly make changes to your application codebase and it isn't needed at production because like we said previously, at production time it's just HTML and JS and nobody ever makes any changes on these files.
Virtual DOM is a memory representation or concept used by React Code just like we have stacks and queues and it not just used at development time. Yes and No. Because I think appropriate parts of react source code which is required to run the application would also be bundled before generating the production bundle.
I would say, don't have a preset way of things, because it is totally upto the developer and the team, because I have seen people using 2 seperate repos because frontend people work on frontend things whereas backend people work on backend things. But there's also a case when everyone's a fullstack developer and you can Technically have it in a single repo with a single package.json and use the backend to serve the frontend files and you have to manually install each react dependency and cannot directly use CRA or create-react-app like generator.
What has 2 repositories to do with front-end deployment in production? You don't need to run webpack-dev-server to server files in production. You can create a production bundle and then setup any http server to serve the generated bundle.
Regarding your current scenario I would say instead of having 2 package.json, you can go with a single package.json and install all dependencies together or go with a monorepo approach using something like lerna or yarn workspaces.
But for a total beginner I would suggest 2 separate repositories to encounter less problems.
And a bonus point if you are not aware, you can write React in pre-ES6 code and also without JSX as well.
1) virtual DOM is basically to say that you are calling a function of react not the actual function which does manipulation on the real DOM
like this one
document.getElementById("demo").innerHTML ="Helloworld"
modifies the actual dom
but this
ReactDOM.render(
<HelloMessage name="Taylor" />,
document.getElementById('demo')
);
if you see this properly you aren't doing anything directly on the dom you are just giving the react function control to do things , internally react take cares of modifying the that dom element demo whenever the react wants to re-render it based on its own logic which is what they claim as optimized which is why people use it in first place. Yes when you build your code with webpack it does include react in it which is part of that minified code, so if you see any of the error stacktrace in development you do see react is the starting point for it
2) I think its a choice to be made, as there are not restrictions on this
3) Coming to deployment , In general if you want use nodejs you might choose expressjs server type of deployment but otherwise generally its better to use a high performance server like Nginx or Apache or else if you just don't want to get into this whole drama of things people generally use heroku based deployment or else people are using special platforms like netlify,surge.sh these days (its super easy to deploy on these platforms).
I believe others have done a pretty good job explaining the React Virtual DOM. In a simple and practical way, I’ll attempt to explain how I (would) manage the deployment of a dynamic website (including medium-sized enterprise systems) using NodeJS and React. I’ll also attempt not to bore you.
Imagine for once that React never existed and that you were building a traditional Server-Side Rendered application. Each time the user hits a route, the controller works with the model to perform some business logic and returns a view. In NodeJS, this view is usually compiled using a template engine such as handlebars. If you reflect for a second, it becomes obvious that the view could be any html content which is then sent back to the browser as a response.
This is a typical response that could be sent back:
<html>
<head>
<title>Our Website</title>
<style></style>
<script src="/link/to/any/JS/script"></script>
</head>
<body>
<h1>Hello World </h1>
</body>
</html>
If this response hits the browser, obviously “Hello World” is displayed on the screen.
Now, with this simple approach, we can do powerful things!
OPTION 1:
We can designate one controller to handle all incoming routes app.get("*", controllerFunc) and render one view for our entire server.
OPTION 2:
We could ask multiple controllers to handle different routes and render route-specific views from our server.
OPTION 3:
We could ask multiple controllers to handle different routes and generate pages on-the-fly (i.e. dynamically) from our server.
If we were building a traditional web application, option 3 would be the only reasonable standard. Here, pages are generated dynamically for different routes. However, with option 1, we can produce a quality Single-Page Application where the response sent to the server is an empty html page but with the built JS script that has the ability to manipulate the DOM – Yes, React! Here’s what such a response might look like:
<html>
<head>
<title>Our Website</title>
<style></style>
<script src="/link/to/any/JS/script"></script>
</head>
<body>
<h1>Hello World </h1>
<div id="root"> </div>
<script async type=”text/javascript” src="/link/to/our/transpiled/ReactSPA.js"></script>
<!--async attribute is important to ensure that the script has access to the DOM whenever it loads. This also makes the script non-blocking -->
</body>
</html>
Clearly, we’re giving all the responsibility to the generated SPA and all routing logic is handled on the client-side (See, react-router-dom). On the server side, we can introduce the concept in option 2 and tweak NodeJS route handlers to listen to another specific route for any REST API communication. If you’re familiar with NodeJS, the order in which routes are registered either by app.get() or app.post() matters.
However, using option 1, we can quickly become limited and only able to serve one Single-Page application from that server. Why? Because we have asked one controller to handle all non-API incoming routes and render one view. We also risk serving an unnecessarily bloated JS file. Users are served the complete website when all they probably wanted was just the landing page.
If we look to the option 2 though, we can tweak things a lot more and serve multiple Single-Page Applications for different routes, all from our server. This approach helps to reduce the sizes of the JS build being sent to the browser. A typical example would be a website that has a welcome page (or an introduction directory), a login page and a dashboard.
By assigning controllers for different routes, we can build SPAs uniquely for those routes. SPA for the intro page, another for the login page, and then another for the dashboard. Yes, the browser would have to load while transitioning between the three, but at least we highly increase initial render time for our website. We can also use the more secure option of cookie for authorization rather than the less secure option of storing session tokens on localStorage.
In a more advanced setting, we could have dynamic websites with different React components rendered as widgets within the dynamically generated page. Actually, this is what Facebook does.
The way to build such SPAs or components is pretty simple. Start up a react project and configure webpack to render the production-ready JS file into your preferred public static directory within the server-side repo. The <script> specified in the view can then easily load these built react components since they exist within the scope of the server-side’s public directory.
In essence, this means one repo with several client directories and one server directory where the destination of the production build files to be generated by webpack for each client project is set to the server’s public static directory. So, each client side’s directory is a project (either full SPA or simple React Component as a widget) with it’s own webpack.config and package.json file. In fact you can have two separate config files – production and development. Then, to build, you use npm ~relevant command~ for either production or development build.
You could then go ahead to host it the way you would host any NodeJS application. Because, the main application is the NodeJS - that's where the server is. Replace NodeJS with PHP and Apache/NGINX, the concept still remains the same.

Why use Express with ReactJS

I'm currently working on a new ReactJS application. In all the previous applications I've built I used Express for the server side rendering. I used Express because routing in production mode wouldn't work if I didn't.
So I've recently discovered that it's posible to just always redirect my React app to my index.html file and let the React routing just do it's work. This also works when I deploy my application to production.
I know Express can be usefull for SEO porposes but other than that I have no idea why I would need to use it. So am I just missing something? Or is it just fine to don't use Express with my React application if I don't need any SEO.
React configured as a Single Page App, renders the express routing all but unnecessary. The standard transition from a web server rendered app to a single page app is to change the server into a REST Web API and any server side data needed from the React App is obtained through AJAX calls.
So in most cases you don't need Express when you are using React to handle your routing except for in less common cases when you might want to use express as a reverse proxy or something.
If you want to do server-side rendering, you'll need a node server (typically but doesn't have to be express) to render your React components. This could not only help with SEO but also allow your page to appear to load faster (you wouldn't have to wait for the JS to download and run before the user sees the HTML).
If you don't care about the benefits, don't use SSR.
when deploying react application it is just usually an html and a JS file. So you need some kind of server to host it. Luckily there are services out there that offers that like S3, Github etc.
You're using Express because it can host the html and js files. So technically you don't need specifically express but you need some server that will host your files.

Using Nodejs Along Side Firebase

I am about to start developing my web application in Firebase. Problem is, currently I have 100s of questions running through my head, and nothing I can find online specifically answers such.
Now from what I understand you can ONLY host assets on Firebase hosting (HTML, CSS, JS), and if you have a backend (such as Node) you will have to use a separate hosting service (like Heroku).
Firebase hosting implies that everything can be done from the browser, but I am not sure how I would get around using a backend.
For instance, if the user enters the url http://___.com/login I would route that in Express to login.html. Also if a user types in /index or /home or even nothing, it would take them to index.html. How would I go about doing this without a backend?
Another big question I have is templating. On Node there are many templating engines, is there such a thing though when just using the frontend?
Would there be a way to get around those two issues above without using a backend? I can see some benefits when using a backend such as server side rendering, and using third-party services such as Sendgrid. But what else would I get out of using a backend such as Node?
I guess I am just a bit confused on how a web application could be done without a backend (that you can access and control). I do not see how templating, routing, and many other things can be controlled by just the browser, and hosted within Firebase.
I plan on using Node (unless all of this is possible without a backend), and I am intending on using React and Redux as well. Can Firebase, Node, React and Redux all be used together?
I know there are a ton of questions above, but I just can not wrap my head around it all. I put all of my main question in bold, thank you!
Firebase Hosting allows you to do single-page app style routing, you'd just add this to your firebase.json:
{
"hosting": {
"rewrites": [{"source": "**", "destination": "/index.html"}]
}
}
As for templating, you'd want to look into frameworks such as React, Angular, Ember, Polymer, etc. to do dynamic content generation client-side instead of relying on server-side templates.
Firebase offers tools that can help you with the most common things you'll need when building an app (auth, database, file uploads, hosting). For these, you won't need a server at all. If and when your app needs additional custom back-end work, you can always deploy separate services that can be called by the client or even just listen to the database and trigger events directly.
And yes, you can definitely use React, Redux, and Firebase together. Hope that helps!

Resources