http-proxy module doesn't work with create-react-app, but works with serve -s build
This is my proxy-server code.
So what it does - it joins 2 api servers on different ports and frontend to a single 80 port. When you open localhost:80/* it should open react frontend (3000 port). When you open /api it gives you data from 4000 port and /secondapi from 1000 port.
My 2 backend api servers are opening completely fine with it.
Also when I start frontend server using serve module it also works fine and returns my frontend part.
But if I start frontend at the same 3000 port using "npm start" my proxy server returns connect ECONNREFUSED ::1:3000
const httpProxy = require('http-proxy');
const http = require('http');
const { maintenanceHtml } = require('./maintenanceHtml');
const proxy = httpProxy.createServer();
const guiUrl = 'http://localhost:3000'; // react frontend app
const apiUrl = 'http://localhost:4000'; // 1st api server
const apiPrefix = '/api';
const fnApiUrl = 'http://localhost:1000'; // 2nd api server
const fnApiPrefix = '/secondapi';
const port = 80;
http.createServer((req, res) => {
let target = guiUrl;
if (req.url.startsWith(apiPrefix)) {
req.url = req.url.replace(apiPrefix, '/');
target = apiUrl;
}
if (req.url.startsWith(fnApiPrefix)) {
req.url = req.url.replace(fnApiPrefix, '/');
target = fnApiUrl;
}
proxy.web(req, res, { target })
proxy.on('error', (error) => {
console.log(error.message)
res.end(maintenanceHtml);
})
}).listen(port, () => {
console.log(`Proxy server has started on port 80`)
});
I think that there is react server settings that I'm not able to find.
There is a little example that you're able to start at your own PC.
https://github.com/b2b-Alexander/react-js-problem
Found solution on github: https://github.com/vitejs/vite/discussions/7620
I got installed new v18.12.1 version of NodeJS.
My main machine has v16.14.0
So I rolled back the version of NodeJS for my project.
Related
http-proxy module doesn't work with create-react-app, but works with serve -s build
This is my proxy-server code.
So what it does - it joins 2 api servers on different ports and frontend to a single 80 port. When you open localhost:80/* it should open react frontend (3000 port). When you open /api it gives you data from 4000 port and /secondapi from 1000 port.
My 2 backend api servers are opening completely fine with it.
Also when I start frontend server using serve module it also works fine and returns my frontend part.
But if I start frontend at the same 3000 port using "npm start" my proxy server returns connect ECONNREFUSED ::1:3000
const httpProxy = require('http-proxy');
const http = require('http');
const { maintenanceHtml } = require('./maintenanceHtml');
const proxy = httpProxy.createServer();
const guiUrl = 'http://localhost:3000'; // react frontend app
const apiUrl = 'http://localhost:4000'; // 1st api server
const apiPrefix = '/api';
const fnApiUrl = 'http://localhost:1000'; // 2nd api server
const fnApiPrefix = '/secondapi';
const port = 80;
http.createServer((req, res) => {
let target = guiUrl;
if (req.url.startsWith(apiPrefix)) {
req.url = req.url.replace(apiPrefix, '/');
target = apiUrl;
}
if (req.url.startsWith(fnApiPrefix)) {
req.url = req.url.replace(fnApiPrefix, '/');
target = fnApiUrl;
}
proxy.web(req, res, { target })
proxy.on('error', (error) => {
console.log(error.message)
res.end(maintenanceHtml);
})
}).listen(port, () => {
console.log(`Proxy server has started on port 80`)
});
I think that there is react server settings that I'm not able to find.
There is a little example that you're able to start at your own PC.
https://github.com/b2b-Alexander/react-js-problem
Found solution on github: https://github.com/vitejs/vite/discussions/7620
I got installed new v18.12.1 version of NodeJS.
My main machine has v16.14.0
So I rolled back the version of NodeJS for my project.
I have a React app where I specified the port number in server.js as
const port = process.argv[3] || 3500;
At the bottom of the same file I wrote:
app.listen(port, () => console.log(`Web service running on port ${port}`));
While the app is able to run in my browser, unfortunately in the console of my text editor it says Web service running on port 3500 even when the url says localhost:3000.
I know that React uses port 3000 as default... but don't know why the app chose to use port 3000 instead of the port 3500 that I specified above.
To try and fix this I tried to install the dev dependency cross-env and in my package.json "start" script I specified cross-env PORT=3500.
After that change, I see that my React app is now running in the browser on Port 3500... but I am unable to avoid the message from the server.js file that says "Web service running on the Port # that I specified in the server.js file".
In server.js when I use const port = process.argv[3] || 3500; in conjunction with the cross-env port 3500 change in package.json... I get the message "Something is already running on Port 3500". So it seems impossible to get the correct console message that the React app is really running properly in the browser on Port 3500.
Full Express server.js below:
const jsonServer = require("json-server");
const chokidar = require("chokidar");
const cors = require("cors");
const fileName = process.argv[2] || "./data.js";
const port = process.argv[3] || 3500;
let router = undefined;
const app = express();
const createServer = () => {
delete require.cache[require.resolve(fileName)];
setTimeout(() => {
router = jsonServer.router(fileName.endsWith(".js")
? require(fileName)() : fileName)
}, 100)
}
createServer();
app.use(cors());
app.use(jsonServer.bodyParser)
app.use("/api", (req, resp, next) => router(req, resp, next));
chokidar.watch(fileName).on("change", () => {
console.log("Reloading web service data...");
createServer()
console.log("Reloading web service data complete.");
});
app.listen(port, () => console.log(`Web service running on port ${port}`));```
Express Server:
you can run express server in the any port you want it to run
const port = process.env.port || 4000 //? can be any port number
the console log you are getting in the editor is from the server and not from the react app.
React App:
by default react app runs in port 3000 if you want to change the Port of the react app then use react-scripts like this
"start": "set PORT= <Your Desired Port> && react-scripts start"
or you can set port directly from terminal like this
PORT=4000 npm start //? or any other port number
app.listen is for express servers. To run a react server use react-scripts. To change port number use the PORT environment variable.
I have recently started learning MERN stack and I made my first front-end application using React and I connected it using an API that I have created using Express. It works perfectly fine on my local machine using localhost.
But whenever I try to upload it to a hosting service, like Heroku for example, it gives me a 404 error whenever I open the link. Is there is a way for me to upload my API into a hosting service for free or is there is something I'm doing wrong in my code ?
const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const app = express();
require('dotenv').config({ path: __dirname + '/.env' });
const URI = process.env.URI;
mongoose.connect(URI, { useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: true });
const connection = mongoose.connection;
connection.once('once', () => {
console.log('connection to database has been initiated sucessfully');
});
const itemRouter = require('./routes/itemsRouter.js');
const orderRouter = require('./routes/orderRouter.js');
const mailRouter = require('./routes/mailRouter.js');
app.use(express.json());
app.use(cors());
app.use('/items', itemRouter);
app.use('/orders', orderRouter);
app.use('/sendMail', mailRouter);
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
console.log(`App is running on port ${PORT}`);
});
Heroku should work out the box if you've followed the setup here Heroku Dev Center.
However, if you're using freshly shipped ubuntu or similar server. You'll need to set up the environment by doing the following:
Install node run time, nginx & a node deamon manager (In this case PM2)
sudo apt install nodejs nginx
npm install -g pm2
Create an nginx config
server {
listen 80;
index index.html;
server_name YOUR_DOMAIN/SERVER_IP;
location / {
proxy_pass 127.0.0.1:NODE_BOUND_PORT;
}
}
Deamonise the Node script
pm2 start index.js
You'll have to restart nginx and create the symbolic links for NGINX to pick up the routing but once this is done, should route as intended.
This problem is similar to a more general question of communicating between server and client, however the issue is probably heroku specific because the server port is provided by heroku in the 'process.env.PORT' variable.
My back-end express/mongoDB app has been deployed on heroku. It listens on the assigned port = process.env.PORT which is a new port every time the server starts
The front end Vue.js runs on the same express server and uses axios for CRUD
I have tried port = process.env.PORT || 4000 in the Vue application but it is always 4000 so the request fails.
Is there some way to pass the port number from the backend Node.js environment to Vue.js components ?
It appears that process.env.PORT is not set in the Vue.js application
Extract from a sample Vue component
.
.
.
import port from '../config';
export default {
data() {
return {
tokens: []
};
},
created() {
let uri = 'http://localhost:' + port + '/tokens';
this.axios.get(uri).then(response => {
this.tokens = response.data;
});
}
};
.
.
.
'config.js'
const port = process.env.PORT || 4000;
export default port;
'server.js' segment
const PORT = 4000;
const port = process.env.PORT || PORT
app.listen(port, () => {
console.log('Express server running on port ' + port);
});
Thanks very much to Gowri for an excellent response that completely fixed the problem.
For newcomers to Vue who follow the many tutorials that have been published, please take note of the need to use a relative path when deploying to heroku. My MEVN app is now working perfectly.
export default {
data() {
return {
tokens: []
};
},
created() {
let uri = '/tokens';
this.axios.get(uri).then(response => {
this.tokens = response.data;
});
}
};
I am trying to start a https node.js server.
I started by creating a certificate and key following this guide:
http://gaboesquivel.com/blog/2014/nodejs-https-and-ssl-certificate-for-development/
and I placed them in my /app_name/security/keys directory.
To start my https server, I have the following:
const https = require('https'),
fs = require('fs');
if(app.get('env') === 'development') {
console.log('dev env!!'); //prints correctly
console.log('port: ' + port); //prints correctly
const options = {
key: fs.readFileSync('./security/keys/key.pem'),
cert: fs.readFileSync('./security/keys/cert.pem')
};
https.createServer(options, (req, res) => {
console.log('https good to go'); //this does not print out anything
}).listen(port);
}
When I go to https://localhost:3000, the page throws an error
This site can’t be reached
localhost unexpectedly closed the connection.
ERR_CONNECTION_CLOSED
But there's no error on the server side console. Furthermore, if i go to the regular localhost:3000, I get:
The localhost page isn’t working
localhost didn’t send any data.
ERR_EMPTY_RESPONSE
Can someone help?
Thanks in advance!
---- UPDATE ----
I'm running on port 443 now. Initially I got an error:
Error: listen EACCES 0.0.0.0:443 so I ran:
sudo NODE_ENV=development nodemon app
Which did not throw any errors. However, when I went to https://localhost:443, I get:
This site can’t be reached
localhost unexpectedly closed the connection.
I used express as a web server.
to install express:
npm install express --save
I took your code, added the usage in express, generated certificate using openssl, and executed it - all looked good, the server was up, listening to port 3000 over https.
My code (which is based on your code...):
var app = require('express')();
const https = require('https'),
fs = require('fs'),
port = 3000;
if(app.get('env') === 'development') {
console.log('dev env!!'); //prints correctly
console.log('port: ' + port); //prints correctly
const options = {
key: fs.readFileSync('/tmp/private.key'),
cert: fs.readFileSync('/tmp/publickey.crt')
};
https.createServer(options, (req, res) => {
console.log('https good to go'); //this does message appears!!! ^_^
}).listen(port);
}
Please pay attention to the way I defined app: var app = require('express')();
You can split this definition into two line if it's more readable:
var express = require('express');
var app = express();
So many problems with your code.
I tested this really quickly.
the keyword app and port is not defined, lines 4 and 7 respectively.
That will throw you a syntax error, preventing the code from continuing any further therefore server not starting up at all.
As I mentioned on my comment, use devtool to debug and use the following line on a CLI devtool server.js -w where the -w watches for file changes and reloads the server on the fly, while developing.
also assuming you named your entry file server.js