ReactJS and NodeJS same server? - javascript

I build a project with nodejs and react. I don't know if I must split in 2 servers, one for the react app and one for API in nodejs and the react app ask request at nodejs server.
Or I must group both in only one nodejs process ? What's the difference ? There are a better choice ?

It's up to you React when builded is just static files, don't get confused by the development server. I would recommend you for the beginning to put them in one node process. Just declare the folder of the static files like this:
app.use('/app', express.static(path.join(__dirname + '/dist/app')));
Also if you are using React Router you should add this as your last router
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname + '/src/index.html'));
});
You can check my template repo with webpack here

Related

Rendering react with node.js in development

I am (very) new to node.js and I am trying to get a development environment started with React.
const express = require('express')
const mongoose = require('mongoose')
const app = express()
// this displays the index.html file
app.use(express.static(__dirname + '/public'));
// trying to see the app.js
app.get('/', (req, res) => {
res.render('app')
})
app.listen(process.env.PORT || 5000);
Right now I am simply trying to be able to view my app.js when I run nodemon. But right now it is only showing the index.html file in the public folder. and when I run npm start it renders both the index.html and the app.js.
I am 100% doing something wrong and am not in my element here. Any help/advice would be appreciated.
My full repo is here for viewing here
Thank you in advance.
Your code is simply serving a static HTML file located in the public directory everytime the user make a GET request to the root (in your case, localhost:5000). It is not interacting with React yet.
Usually when starting a project with React (frontend) and Node (backend), you would create them as separate projects, in separate repositories.
So you could create a React application using a bootstrap such as create-react-app running on PORT 3000 and in another terminal tab, start your NodeJS application in PORT 5000 like in your example. Then, you can call your backend endpoint from your frontend React application, by referencing http://localhost:5000
By doing this, your backend code don't need to serve static files anymore, it can return data such as JSON and make connections to a database for example.
Since your question is not specific enough, you could be talking about server side render. In server side render apps using Node and React, you have a frontend built with React and a Node server that will return the same React code as a string, using the react-dom/server package to help. This is more complex, but basically you will have the same React code on the client AND on the server. There are performance benefits, because the user can see some content rendered right when he enters the page, without having to wait the React bundle (javascript file) to load. If you want to know more about creating a server side render app with React and Node, there is a nice digital ocean tutorial here
If you want to connect your react js project to the node js
In Development
you simply run their server and start it
In Production
You can use sendFile function coming from express.js to run the frontend
https://dev.to/loujaybee/using-create-react-app-with-express

Combine Angular 2 application server and REST server modules

I am creating a new Angular 4 application. I have followed it's official tutorial https://angular.io/tutorial/
The application server is started using ng serve command.
I have created a separate node js (+express) server that provides the REST services to the main app on a different port.
Is there any way to serve the main angular application from the same nodejs/express server so that i don't have to use two servers for the application?
I have used typescript which needs to be somehow compiled into plain javascript before statically being served via nodejs, if i understand it right?
Absolutely, just use ng build and serve the dist folder of the built application, or even the src. Example:
const staticFor = rel => express.static(path.resolve(__dirname, rel));
const app = express();
if (!config.production) {
app.use('/node_modules', staticFor('../node_modules'));
// In development we do not copy the files over, so map used path
}
app.use('/', staticFor('../dist/app'));
const appPath = path.resolve(
__dirname,
config.production ? '../dist/app/index.html' : '../src/app/index.html'
);
app.get('/yourAppPath/*', (req, res) => {
const markup = fs.readFileSync(appPath, 'utf8');
res.send(markup);
});
Dont forget to require the right libraries.

How to Integrate angular 4 or higher with express

i want to integrate angular 4 or higher than that with my existing express folder.
As i am new to mean stack development i want clean and understandable steps how to integrate angular with express.
Anyone having reference links for the following::
How to integrate express and angular
how to use mongoose in it.
And crud example for mean app development.
Integrating Angular and Express can be done through a single server.js file placed in the root directory of your Angular project. Use Angular CLI to ng build --prod and generate a dist/ folder. You can then link the dist/ folder through the following code in your server.js file and running node server.js.
// Define variables
const express = require('express');
const app = express();
// Use the /dist directory
app.use(express.static(__dirname + '/dist'));
// Catch all other invalid routes
app.all('*', function(req,res){
res.status(200).sendFile(__dirname + '/dist/index.html');
});
// Start the server
app.listen(process.env.PORT || 3000);
The Mongoose Docs are very good, but if you need a video, this one: Mean Stack Front to Back: Part 3 is a nice code-along you can work with. The Mongoose part starts about 90 seconds into the video.
This website gives a nice CRUD Example and also goes into Mongoose as well.

create-react-app shows an error of "You need to enable JavaScript to run this app."

I use express for my API. I have a folder named app and another folder named server. app is the client app, using create-react-app as boilerplate, while server is express.js app for the API.
in the app.js file of the server, I wrote
app.get("*", function (req, res) {
res.sendFile(path.resolve(__dirname, '../app/build/index.html'));
})
But then when I call any API endpoint, I get
You need to enable JavaScript to run this app.
in the response. I'm confused; what's wrong?
In the build directory you have more files that just index.html. You also have build/js/main.buildNumber.js and build/css/main.buildNumber.css.
So when your frontend makes a request to https://yourdomain.com/css/main.buildNumber.js, it incorrectly returns index.html not main.js.
Instead, you should serve the contents of the build folder statically with express.static
app.use('/', express.static(__dirname + '/'));
Or you can look into the "serve" node module to host your app. This will work nicely with react-router. npm i -g serve then cd build then serve . --single -p 5000. This will serve your app on port 5000 (http://localhost:5000).
For me, the issue was that I was mixing styles for functional and class based components. Double check that you don't have any dangling this keywords, or perhaps some missing of the same.

Setting up Express with Angular

I can setup Angular in my web app using ASP/Visual Studio rather easily, but I want to get into the Node world, more specifically Express. I'm not truly understanding a basic route handler for Express, that will support the paradigms that Angular has.
For example, when setting up an Express file, there's a million examples, but almost all of them use Jade for templating, and I'm against Jade's syntax and have no desire to utilize it.
So far, I have this for my Express server (I have commented out some questions regarding my decisions made so far):
var express = require('express'),
path = require('path');
var app = express();
var env = process.env.NODE_ENV || 'development';
// 1) Is this really necessary if I'm going to utilize Angular routing for views?
app.set('views', path.join(__dirname, '/app/views'));
app.use(express.static(__dirname + '/public'));
// 2) I'm assuming this is the desired pattern for utilizing Angular.
// A catch-all handler that serves up an html file, which will then
// hand off the rest of the routing to Angular?
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname + '/public/index.html'));
});
const PORT = 3000;
app.listen(PORT);
console.log('Listening on port: ' + PORT);
The questions I have are:
Is app.set('views', ...) necessary in an Angular app through Express or is it really intended for a Jade/EJS templating workflow? If it's useful to Angular, what path should I point it to? My Angular views? Or just the static html file that will serve as the container to all angular views?
I'm assuming app.use(express.static(...)) is still needed for ensuring Express can serve up public static resources, like css/javascript.
Is an app.get('*', ...) { res.sendFile('path/to/index.html') } route handler the accepted pattern for serving up one html file, which will contain all necessary Angular usage?
For Angular, is it normal to only have one html file for the entire of your application, and then just use Angular's routing and controllers/views to handle the rest?
Is app.set('views', ...) necessary in an Angular app through Express or is it really intended for a Jade/EJS templating workflow? If it's useful to Angular, what path should I point it to? My Angular views? Or just the static html file that will serve as the container to all angular views?
If you need to render a view on the server side and then send it to the client, you need this. Otherwise (in your case) no. You can just send the file to the user or generate a user-specific output based on the parameters that user has sent to the server. It could be anything, HTML file, json or just simple text.
I'm assuming app.use(express.static(...)) is still needed for ensuring Express can serve up public static resources, like css/javascript.
You are right. If you need to serve the static content as well, the best way is to use express.static, however you can catch the requests and serve the content by yourself.
Is an app.get('*', ...) { res.sendFile('path/to/index.html') } route handler the accepted pattern for serving up one html file, which will contain all necessary Angular usage?
If for each and every other requests that the previous routes didn't catch, you need to send the exact same file, yes it is fine.
Remember if you need to serve other HTML files as templates and they are not in the same directory as you pointed in express.static to, the client could not have access to html files. I'll discuss it in a bit.
However, I believe it is a good practice to define all the routes and not just put a * to catch them all. It is better to define a pattern at least, it would be easier to maintain the code later on.
For Angular, is it normal to only have one html file for the entirety of your application, and then just use Angular's routing and controllers/views to handle the rest?
Depends on your application. In most of the cases yes.
I've done several big angular projects, I only have one route that actually serves the main html file, and one that serves static files (pictures, js, css). I also have a route that points to the templates directory which should be served as static contents. Those are the templates that AngularJS need to work with.
For the communication between your angular app and the server, you'll probably need other routes as well. You could create RESTful API end-points to create a communication layer for the client and the server.
I usually have these two lines in the server code to keep the all the templates in the same folder. It makes it easier to manage and define work flows:
app.use(express.static(path.join(__dirname, 'public')));
app.use('/templates', express.static(path.join(__dirname, 'templates')));
For communication between the server and the client:
app.post('/login', function (req, res) {
// deal with login information ...
res.send({
done: true,
errors: []
});
});
app.post('/search', function (req, res) {
// do the search ...
res.send({
done: true,
results: []
});
});
Remember if you use * at some point in your app, the other routes that you defined after that, will never catch the request.
And
I'm against Jade's syntax and have no desire to utilize it.
Yes, me too! But there are other options as well, I personally prefer ejs. If you are using express-generator you can just pass -e switch and it'll create everything compatible with ejs.
$ express -e
Also, take a look at here.

Categories