I have a create-react-app where I split the client side to run on port localhost:3000 and my node js/express api side to run on port localhost:9000. I was using a Proxy at localhost:9000 to make my api requests from my client side to my backend. Now, I want to deploy this app. I have done npm run build on my client side and have that folder.
I was using the static server (serve -s build) at port 5000 to see it. However it is not getting any response or communicating with my express server. I don't even get any errors. I am certain the server is running but it seems they are not communicating. I also have CORS enabled.
Is this possible to run the build folder separately from my express server, have them running on two separate servers or I do I have to serve the static build from my express backend? In the end I'm going to use Apache but I'm trying to get the build up and running, communicating with my backend like how it was before I did the build. Please help!
[app.js(express/node js)]
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var cors = require('cors');
var indexRouter = require('./routes/index');
var APIRouter = require('./routes/API'); // require route
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(cors());
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use("/API", APIRouter); // telling express to use this route but need to require it
app.use(function(req, res, next) {
next(createError(404));
var err = new Error("Not found from app.js")
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
console.log(err);
});
module.exports = app;
[index.js(express/node js)]
var express = require('express');
var app = express();
var cors = require('cors');
var path = require('path');
var cookieParser = require('cookie-parser')
var secret = require('./config')[env]
var env = process.env.NODE_ENV || 'development';
var config = require('./config')[env];
const basicAuth = require('express-basic-auth');
const auth = basicAuth({
users: {
[config.adminCredentials.user]:config.adminCredentials.password
}
});
app.use(cookieParser(config.adminCredentials.secret));
app.use(express.json());
app.use(cors());
app.use(function(err, req, res, next) {
res.status(err.status || 500);
console.log("error:", err);
});
/* This is for deploying build folder , app is then hosted on port: 9000 */
// app.use(express.static(path.resolve(__dirname, '../../client/build')));
// //All other GET requests not handled before will return our React app
// app.get('/', (req, res) => {
// res.sendFile(path.resolve(__dirname, '../../client/build', 'index.html'));
// });
app.get("/authenticate", auth, (req, res) => {
const options = {
httpOnly: true, //cookies are only accessible from a server
signed:true,
maxAge: 60 * 60 * 1000, // 1 hour
sameSite:true // prevents the cookie from being sent in cross-site requests
};
if(req.auth.user === "*****") { // response reaches back to client if and only if the credentials sent along match with the request match
res.cookie('name', '*****', options).send({screen:'******'});
}
});
app.get('/read-cookie', (req, res) => {
if(req.signedCookies.name === "*****") {
res.send({screen:'*****'});
}
else {
res.send({screen:'auth'});
}
});
app.get('/clear-cookie', (req, res) => {
res.clearCookie('name').end();
});
app.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
bin/www (express/ node)
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('api:server');
var http = require('http');
const fs = require("fs");
const path=require('path');
var cookieParser = require('cookie-parser');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '9000');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port, () => {
console.log(`Server listening on ${port}`);
});
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
Client package.json
{
"name": "client",
"version": "0.1.0",
"private": true,
"dependencies": {
"@emotion/react": "^11.9.3",
"@emotion/styled": "^11.9.3",
"@fortawesome/fontawesome-svg-core": "^1.2.34",
"@fortawesome/free-brands-svg-icons": "^5.15.2",
"@fortawesome/free-regular-svg-icons": "^5.15.2",
"@fortawesome/free-solid-svg-icons": "^5.15.2",
"@fortawesome/react-fontawesome": "^0.1.14",
"@mui/icons-material": "^5.8.4",
"@mui/material": "^5.9.1",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"axios": "^0.21.4",
"cors": "^2.8.5",
"node": "^17.4.0",
"prop-types": "^15.7.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.3.0",
"react-scripts": "3.4.3",
"web-vitals": "^0.2.4"
},
"scripts": {
"start": "HTTPS=true react-scripts --openssl-legacy-provider start",
"build": "react-scripts --openssl-legacy-provider build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"proxy": "http://localhost:9000",
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}