So here is my issue in a pickle: btw I had some trouble finding out how to do this through google and I did try using StackOverflow but couldn't find the exact answer
So I have a ReactJS website where I use
yarn start
to run and it launches on localhost:3000
I want it to launch on localhost:3000 while an express server also launches on that server, aka start the react server up in express.js.
It seems like every tutorial I've found, most are outdated, and the remaining ones are guides to turn react into a static website and THEN use express. I would like to keep react on the server-side for advantage of react-router
Edit1: So basically when I have an expressjs server
THE DATABASE DETAILS HAVE BEEN REMOVED, THAT LINE ISNT AN ERROR
const express = require('express'); var app = express();
var mysql = require('mysql'); var connection =
mysql.createConnection({ host :
database : 'main' });
connection.connect()
app.post('/users', function(req, res) { var user = req.body;
res.end('Success'); })
app.listen(3000, function(){ console.log('Express sever is listening
on port 3000') })
//connection.end()
I also start the create-react-app server with yarn start and it launches on localhost:3000 but this expressjs server overrides that.
So I want to connect the two to be able to send post requests
I just recently worked on a sample repo that implements this strategy. There are a few ways this can be done, but the simplest way to do this will be to start the express server as a second server that will run on a different port, ie. 3001. You can then use concurrently to launch both the react server (I am assuming webpack) and the express API server in a single command.
Here is a tutorial that shows how this can be set up. You should pay attention to the section in this tutorial about proxying requests from the client (browser) through the webpack server. There are some considerations to think about with regards to CORS configuration if you do not proxy requests through the webpack server.
Here is my proof of concept repo where I implemented just what you are looking for: react client, and express server. It can be run via concurrently or with docker (compose).
You can change the port on which express is listening:
var server = app.listen(3001, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port)
Change 3001 to any valid port number
Related
So I've just created simple chat app with React, NodeJS, Express.JS and SocketIO. I'm going to deploy it on Heroku.
The problem is I'm not sure could I run both frontend and backend on the same URL. When I first created this chat locally, I've run front-end on localhost:3000 (default by Create-React-App) and backend on localhost:8000.
For the front-end side, I did it like this in external API.js file:
import io from 'socket.io-client';
let socket;
export const api = {
open: () => {
socket = io('http://localhost:8000');
}
}
For the backend side, I did it like this:
let express = require('express');
let io = require('socket.io')(8000);
So, you see, they're both on different ports. On my computer, it works perfectly. I'm not sure they could work locally on the same port (if I'm trying to switch 8000 port on back-end side to port 3000 it unfortunately doesn't work correctly - front and backend can't work on the same port, HTTP 404 error occurs).
My question is: is there any reason/is it even possible to put it on the same port? Because here's the problem number 2:
I've tried to deploy it on heroku, for the front-end side I've used Heroku Buildpack for create-react-app and it works fine, but totally don't know how to use it to deploy server-side. Should I create separate heroku address for the backend? And, at the code above, change paths like:
let socket;
export const api = {
open: () => {
socket = io('http://myherokuaddress');
}
}
and
let express = require('express');
let io = require('socket.io')(http://myherokuaddress);
?
In heroku you can't define port manually. use this code instead of port 8000.
process.env.PORT
You can do what Zenith said, however, the best practice is to use different servers for frontend and backend code, that way you can build mode frontend apps that uses the same backend code. And, if for some reason, your frontend server is down, you will only need to host the frontend code anywhere else and still using the same backend.
I have a React-Express app that pulls data from a MongoDB database on mLab.
On my server.js file, I have the api port set as such:
var port = process.env.PORT || 3001;
And it listens as such:
app.listen(port, function() {
console.log(`api running on port ${port}`);
});
Currently, in my React app, one of the components makes an AJAX call to the database on mLab using the url of "http://localhost:3001/api/data", which works fine and pulls the data I requested.
However, when I deploy the app to Heroku, I'm not sure how to configure the server.js and the url in the React app, so the React app is able to pull the data from the database.
I've conferred with mLab, and there are no issues, and I've conferred with Heroku, and this is beyond the scope of their support.
UPDATE: Is it that the process.env.PORT variable needs to be set or redirected?
Any ideas what I need to do?
Thanks!
If your express app is serving both your bundled react app and your api, you need to make sure that express knows that the /api endpoint needs to be NOT served to the react app.
Not sure what your server code looks like, but this has worked for me:
if (process.env.NODE_ENV === 'production') {
app.get(/^\/(?!api).*/, (req, res) => { // don't serve react app to api routes
res.sendFile(PATHTOREACTBUNDLE));
});
};
Basically, you want to tell express that, if in production mode (deploy on heroku), serve all endpoints, except the api endpoint (/^/(?!api) to your react bundle.
I've been working on my chat application on my localhost machine (which works fine), but when I'm trying to host it on Github or 000webhost, I get this error polling-xhr.js:264 on both hosts (both hosts have an https connection). I am using cfenv to parse Cloud Foundry-provided environment variables. Here is a picture of the error in question:
It'll keep going like that...
Here is a look at my code:
server.js
var cfenv = require('cfenv');
var appEnv = cfenv.getAppEnv();
var express = require('express');
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(appEnv.port, appEnv.bind, function(){
console.log("Server starting on " + appEnv.url);
})
app.use(express.static(__dirname + '/'));
... // rest of socket.io code
index.html
...
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>
...
socketService.js (btford's socket.io extension)
app.factory('socket', function(socketFactory){
return socketFactory();
});
I've tried various code suggested here on StackOverflow, but I can't seem to get it right. My code works very well with localhost, but it doesn't work when there is an actual server such as one mentioned above.
Thanks a lot for the help!
both hosts have an https connection
But you have in your server code:
require('http');
Try using the https module instead of http. That might explain why the app only works in localhost. Hope this helps :)
EDIT
You should also verify that your server is listening on port 443 instead of 80
I just found out from a good friend that the servers I was hosting on does not support node.js and that's why it didn't work. When my friend hosted his server with it installed, it worked very nice.
How to setup the dev environment where the UI is to be re-done using AngularJS and typescript etc but we already have an existing set of services hosted in rest/osgi bundles.
All the development models with AngularJS and type script talks about node/npm etc but how do we hit existing services with that? do i need to enable cors etc for development?
how is UI development done in these kind of projects as i believe not all projects are done from the beginning and have liberty to use node at server.
Well, usually from an angular app you define some kind of angular service that talks to your api in a standard way.
It's true that most "Frontend" projects use a mocking server during development but it isn't hard to hard to use a real server for this, provided it's not you own production server, obviously.
About the cors issue, I use to let CORS fully open during development ,and have a minimally accesable configuration on production, depending on your project.
After some research we have finalized the DevEnv and it's working out very well.
used angular cli for development
used proxy server to make the calls made to 4200 port to redirect to express server running at port 3000
package.json:
"start": "ng serve --proxy-config proxy.conf.json",
finally wrote a small express server to login to existing server and then pipe all requests!
This was our code:
var app = express();
//enable cors
var cors = require('cors')
app.use(cors());
//relay all calls to osgi server!!
app.use('/a/b/c/rest', function (req, res) {
var apiServerHost = "https://" + HOST + ":" + PORT + "/a/b/c/rest";
try {
var url = apiServerHost + req.url;
req.pipe(request(
{
headers: headers,
url: url,
"rejectUnauthorized": false
})).pipe(res);
} catch (error)
{
console.log("Error " + error);
}
} // Added by review
No mock required
I have a Node/Angular app I'm trying to deploy. It uses two node servers: One to essentially serve the app; another to get data from an API, when a specific port is requested by the app, and store that data locally.
I've got it working perfectly on my own local machine. However, when I deploy to production environments -- either Heroku or AWS Elastic Beanstalk -- I find that the second script either won't run or won't start properly. The end result is, it doesn't get the data I need.
Here are the two scripts; they're both set to run in package.json under "start": "node main.js & node node-server.js"
main.js (again, this one seems to be serving the app just fine):
var express = require('express');
var app = express();
app.use(express.static(__dirname + '/app'));
app.listen(process.env.PORT || 3000);
node-server.js (the one that doesn't seem to work; no data is gathered or populated in the app):
var http = require('http');
var port2 = 1234
var fs = require('fs');
//We need a function which handles requests and send response
function handleRequest(req, res) {
request.get({
url: 'http://sample-url.json',
qs: {
url: 'http://sampletool/pb/newsletter/?content=true'
}
}, function (err, result) {
res.end(result.body);
fs.writeFile('app/data.json', result.body, function (err) {
if (err) return console.log(err);
console.log('API data > data.json');
});
});
}
//Create a server
var server = http.createServer(handleRequest);
//Lets start our server
server.listen(port2, function () {
//Callback triggered when server is successfully listening. Hurray!
console.log("Server listening on: http://0.0.0.0:%d", port2);
});
Then, the main Angular app calls this port (http://0.0.0.0:1234) when the page is loaded, to request new data.
Elastic Beanstalk is using nginx, something I'm not super familiar with and that I don't have running on my local.
Is there something big I'm missing in configuring multiple node.js servers to be running on different ports in a production environment? Thanks in advance for any help.
For security reasons, cloud service providers typically allow the usage of only one port (which is dynamically and randomly assigned to the PORT environment variable) for an application to use from a node server. Read this section from Heroku documentation to understand more about this.
This is why the main app (main.js) that uses process.env.PORT is working and the other app (node-server.js) that uses hard-coded 1234 is not.
This question has some pointers about the feasibility of multiple ports on Heroku (though, there is no good news there, I am afraid).
As how to go about fixing this, one thing that could be tried is to split this into two separate apps that are deployed separately with separate package.json etc.