NodeJs React Proxy - Backend Api Request - node.js

I am currently running a NodeJs with Express Framework and React as my frontend. When I make my request on the development machine the login (passport-google) works flawless. Since I added https to the production server it does not work anymore in google chrome but it is working in safari and IE.
I believe the request is not getting proxied to the express server.
"proxy": {
"/api/*": {
"target": "http://localhost:3001",
"secure": false
}
Proxy settings in react
This is the auth route
router.get(
"/auth/google",
passport.authenticate("google", {
scope: ["profile", "email"]
})
);
router.get(
"/auth/google/callback",
passport.authenticate("google"),
(req, res) => {
res.redirect("/dashboard");
}
);
Thank you

Not sure how it could work in Safari and IE and not in Chrome, but understand that Create-React-App server does not exist in production.
If you are deploying to Heroku, everything changes. Before you deploy to production in Heroku you have to build your React project. When you build your React project, CRA takes all the JavaScript and CSS files and run Webpack and Babel over all those files and save a final build into a build/ folder.
When the user visits your application on Heroku, you are only running the Node/Express API and it sends the user back to the HTML file and the newly built JavaScript file placed in the build/ folder.
npm run build is what you would run before deploying to production.
So when you move into production, you just need to build the application, commit it, deploy to Heroku and you leave it up to the Express server to serve all the different JavaScript files.
So you only need to worry about the proxy for your development environment because CRA does not exist inside production.
You should be using relative routes in your React application.
The entire idea behind the proxy is to re-route requests from localhost:3000/auth/google to localhost:5000 because you are running the two servers in development so the API request has to be proxied, but when deployed you no longer make use of CRA, CRA only exists to use in development to help us create good quality React applications.
Localhost 3000 and 5000 cease to exist when you deploy to production in Heroku at least.

Related

React *create app* won't render when I go to localhost

I have spun up a React app using create-react-app and have my index.js file as below.
import React{ReactDOM} from "react";
import App from "/componects/App.js";
ReactDOM.render(
<App/>,
document.getElementById('root')
);
My server.js file is as
const express = require('express');
const app = express();
app.get("/", function(req,res){
res.sendFile("fullpath/index.js")
});
app.listen(3000, function(){
console.log("app listening on port 3000");
})
I have checked my root route and it works when I don't send the full path. I do specify the full path in the code, but I want to keep it private for this post.
I do have a jsconfig file. When I go to localhost I receive all as plain text of the file. I only get the code itself. How can I fix this?
Quickly answer
You are totally wrong and you are confusing technologies: Node.js and React.
Usually you cannot mix these technologies.
As a summary, Node.js does not understand React code, that is why the following line in your code is unexpected, crazy and will fail:
res.sendFile("fullpath/index.js")
res.sendFile is for Node.js server-side rendering (SSR)
index.js is React code
If your create-react-app workspace is correct and standard, execute this line to start your react code in developer mode:
npm run start
If your react code is fine, the classic http://localhost:3000 will open on your local browser.
Long answer
Concepts
Server-side rendering (SSR) — the traditional rendering method, basically all of your page’s resources are housed on the server. Then, when the page is requested (commonly from web browsers), the HTML, JavaScript and CSS are downloaded. Also frameworks can dynamically can create the HTML-based on back end logic and finally download it. At this point, a lot of frameworks offer wonders for creating apps in no time with "amazing" functionalities.
Technologies: Java, C#, Python, Node.js, etc.
Client-side rendering (CSR) — Which is sometimes called "Frontend rendering" is a more recent kind of rendering method, this relies on JavaScript code executed on the client side (browser) via a JavaScript framework. So, when page is requested, a minimal, little or empty index.html, CSS and JavaScript content were downloaded. Here JavaScript is responsible to send or receive data and update a minimal section of the page without an entire page refresh.. Finally when user clicks or triggers some event, JavaScript code will send or receive the data commonly to an API REST (JSON) using an async call (Ajax).
Technologies: React, Angular, Vue.js, Aurelia, jQuery, pure JavaScript, etc.
Node.js
Is used in SSR frameworks
React.js
Is a CSR framework
Webs developed with React are called SPAs (single-page applications)
How can a CSR web be served?
In the developer stage (laptop/pc) you just need to use some kind of hot reload server (usually Node.js) which translates React into pure JavaScript code and link it to your browser.
These kind of servers are provided or developed by framework creators (Angular, Vue.js, React, etc.). Usually, they are pre-configured in your package.json as: npm run dev or npm run start
In testing/production stage, you should not use the hot reload server. You should perform a build which translates react into a pure JavaScript code. Usually is the command npm run build and the result are new files on some folder in your workspace: index.html, bundle.js, main.css, etc.
These files are ready to published on any HTTP server from minimal to a complex servers:
Apache
nginx
haproxy
Tomcat
WildFly
IIS
free/paid web FTP services
any decent server on any technology capable to serve HTML content.
React in the developer stage
If you are using create-react-app in a correct and standard way, there is a start script in your package.json file ready to use:
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
I advice you to change it from start to dev to make it more intuitive. Let’s empty the start script to be correctly configured for the next stage.
React in the testing/production stage: Basic
If your React code is ready to be tested or used by real users in the real world, and your create-react-app workspace is correct and standard, these are the required and minimal steps:
install a minimal Node.js HTTP server
npm install http-server --save
add this in your script main:
"start": "http-server ./build"
execute npm run build
if there is no errors and your static files are created (index.html, CSS, JavaScript, etc.), perform:
npm run start
For more information (custom port, etc.) check this minimal Node.js HTTP server implementation:
http-server: a simple static HTTP server
React in Testing/Production stage: Docker
If your package.json has correctly configured the standard scripts:
npm run build
npm run start (with http-server or another)
You could use Docker to deploy it on any Linux server in this universe:
FROM node:10
COPY . /opt/
WORKDIR /opt/
RUN npm install
RUN npm run build
ENV PORT 8080
EXPOSE 8080
ENTRYPOINT ["npm","run","start"]
Linux is the only option for real environments. Windows and Mac are just for the developer stage
React in the testing/production stage: Advanced server
What if your requirement needs:
user sessions
login/logout feature
user inactivity expiration
JWT OAuth 2 token refresh
any other feature that React or any CSR/SPA was not designed for
In this case you need an advanced server implemented in some technology like: Node.js, Java, Python, PHP, etc.
These implementations:
should expose your endpoints like: /login, /logout ready to be called from your React, Angular, or Vue.js
should handle the user session with any common way: memory, Redis, MongoDB, etc.
offer a login: basic authentication, Google, Microsoft, etc.
My first attempt was:
https://github.com/jrichardsz-software-architect-tools/geofrontend-server
I am planning a revamp with more features and unit tests.
React in the testing/production stage: Advanced API/microservices
All of the features explained in the previous paragraph could be implemented on any back end REST API or microservice.
With that, your CSR/SPA builds will still be static and won’t need any crazy HTTP server. Just the basics as explained at the start of this answer.
Express / Node.js is case-sensitive. You need to provide an absolute path to the file:
const app = require('express')();
app.get("/", function(req,res) {
// Absolute path
res.sendFile("C:/Users/%username%/fullpath/index.js")
});
app.listen(3000, function() {
console.log("App listerning on port 3000");
});
A relative path is when you are in a directory, and specify a file without specific location:
# Absolute path
C:/Users/John/path/to/file.txt
# Relative path
path/to/file.txt

How do I proxy requests for static files on my node server to my react development server?

I have a node.js server that serves the built static files of my create-react-app at /admin. The problem is that anytime I make a change to my react app I have to build the files over again to see the updates. Instead, I'd like to proxy requests for my frontend at /admin to my dev server that comes with create-react-app, running at localhost:3000, because this would allow for a much faster development experience.
This is what my server looks like now:
// app.ts
...
const app: Koa = new Koa();
app.use(mount('/admin', serve(__dirname + '/build')));
...
And this is what I tried:
import proxy from 'koa-better-http-proxy';
const app: Koa = new Koa();
app.use(
mount(
'/admin',
proxy('localhost:3000', {})
)
)
What ends up happening is the requests for static files still go out and the response gives an index.html file but the JS doesn't seem to run and it gives me errors:
Uncaught SyntaxError: Unexpected token '<'
I've also played around with the proxy header settings to adjust content-type to application/json but I had no success there either.
Due to the environment, I cannot just run the node server in one terminal and the react app in another. The request comes from a verified 3rd party and must go through my node server first before being served the frontend portion of my app.

Serve more then one angular app on same nodeJs server

I have 2 angular apps one is web and other one is admin. I used NodeJS and Express server to serve this app. For the web url is staring with the / (ex: mydomain.com/) and its work fine. Now i want to access admin panel via mydomain.com/admin but its show me error in console.
Error: Cannot match any routes. URL Segment: 'admin'
Note : Both apps ( web and admin ) are separate angular app.
I tried to serve admin interface using proxy_pass in nginx configratio, But it not worked
Here is my routing congigation in NodeJs Server
app.js
//Routing
const WEB = require('./routes/web')
const ADMIN = require('./routes/admin')
//app.use('/',WEB);
app.use('/admin/',ADMIN);
app.use('/',WEB);
/routes/web.js
Router.get('*',(req,res) =>{
// server from angular build using comand ng build
res.sendFile(path.join(APP_PATH,'build/index.html'));
})
/routes/admin.js
Router.get('*',(req,res) =>{
// server from angular build using command ng build
res.sendFile(path.join(APP_PATH,'admin/index.html'));
})
How can I serve two different apps using the same nodeJS server?
This should work
app.use('/',express.static('build'));
app.use('/admin',express.static('admin'));

How to combine vue-cli development mode with server-side api?

I'm new to vue and kind of confuse here.
I'm using vue-cli to build a vue app, I understand I can run a development server with npm run serve which is referenced as a script in my package.json for vue-cli-service serve
But my app need some data coming from a local node.js server. I cannot request this server from development mode because it's running on a different server.
To make my app work I'm obligated to build for production with
npm run build
Then to ask my node server to render by default the produced index.html file.
How could I combine development mode and my node server?
What would be the best way to make this work?
Thanks a lot
I stumbled across this, and found the answer buried at the bottom of the comments list, so I thought I'd highlight it.
This answer is taken from #Frank Provost comment, which really should be the accepted answer. As mentioned in his link https://cli.vuejs.org/config/#devserver-proxy all you need to do is create/edit vue.config.js file in your (client) project root to include this:
module.exports = {
devServer: {
proxy: 'http://localhost:3000' // enter dev server url here
}
}
Then start your dev server as usual from your server project:
[server-root]$ npm run dev
And run your client project from vue-cli project
[client-root]$ npm run serve
Then when you visit the client url (usually localhost:8080) all api requests will be forwarded to your dev server. All hot module replacement still works on both client and server.

Serving Node Server and Angular 4 application in one command

I am starting a new project which is using Angular 4 for frontend designing and the application will need some rest api's for which I have decided to use node. I am using angular cli for creating angular app and I know how to create angular app and node server but I want to know how will I connect these two things such that when I do ng serve both the server and angular app gets compiled and run. What basic changes in the project structure or some file is needed to be done?
I'm currently building a full-stack Angular app with a Node/Express backend and was wondering the exact same thing. However, despite what that scotch.io tutorial tells you, creating both the Express server and the Angular app in the same directory is NOT the best way to go about it.
What you want to do is set up your Express server in one project and serve it in one terminal window, then serve your Angular app in a separate terminal window but have it point to your locally-running Express server instead of the default dev server that's included with the Angular CLI (the ng-serve command).
Here's a Stack Overflow answer and also a Medium article that answered all of my questions for how to set this up (fortunately, it's not too hard).
Here's what I did Shubham. I went into the Angular-Cli and changed "outDir": to "../public"in other words it will look like "outDir": "../public". The ../public folder is my Express static folder set in my app.js file with app.use(express.static(path.join(__dirname, 'public')));
Keeping in mind I have nodemon installed globally, and in my package.json file, "start": "node app" I simply run nodemon from this dir to start my server and both Angular and Express run on the same server.
I have seen some people say it's not good to run static filed on the Node/Express server, but for development I'm not sure it matters. Although I'm a novice when it comes to js frameworks etc. Here's the project files on my github acct: https://github.com/chriskavanagh/angularauth.
Edit: You must run ng-build (in your Angular dir) whenever you change code.
First, in Angular project do ng build, it will create dist folder (static folder).
Second step, paste the following code in backend servers entry point file.
app.use(express.static(path.join(__dirname, 'dist/')));
app.get('*', (req, res) =>{
res.sendFile(path.join(__dirname, 'dist/index.html'));
});
And after the above thing is done run backend server: node filename
Note: in give proper path where your index.html file is located in dist folder.
The node server and the Angular app are two different things.
In order to run the node server you should use the command:
node ServerName.js
In order to run the angular app you should use the command:
npm start OR ng serve
In your case, the connection between the two is made by http requests.
For example you could use 'express' in order to implement rest services in your node server and then send an http request to the server in the current route.

Resources