8

I am building a simple project using React and I want it to be connected to a database (mongodb Atlas). however, I can only connect to my database using Node. Is it possible to run both Node and React on the same port 3000?

I also use Express together with Node because I find it very convenient using ejs files when making new pages with the same navBar and footer.

Is it possible to run these 3 guys together in one port?

Spicy Sauce
  • 115
  • 1
  • 1
  • 9
  • 1
    Neither react nor node use any network ports as they have no networking capabilities themselfs. It's the web server (e.g. express js) which uses node as the runtime environment or the database server that use ports. You can serve your assets (react app, html, css) from the same web server. – trixn Apr 25 '21 at 14:09
  • yup serve the build folder with node js ,static pages – Shubham Dixit Apr 25 '21 at 14:11
  • You might also edit your question with a parenthetical: Is it possible to run Node and React in the same port? (And can I use my Express ejs pages to render my React components?) – Luke Apr 25 '21 at 18:03

5 Answers5

5

You can proxy your api by adding the following proxy field to your package.json in your react project

  "proxy": "http://localhost:4000"

Now in the frontend application you can make fetch API call using the app port e.g.

fetch('/api/user') // this calls -> http://localhost:4000/api/user

Read more here:: Proxying API Requests in Development

KhaledMohamedP
  • 5,000
  • 3
  • 28
  • 26
2

Yes and no. In production Express will serve a static route pointing to your build folder, on the same port. In development mode, Express and React will need to separate ports. You can easily achieve that by setting Express on port 5000 and React on port 3000. Then you will need to declare this "proxy": "http://localhost:5000", in your React package.json. You can even run both Express and React simultaneously in one command if you install the package "concurrently".

Sylvain
  • 509
  • 1
  • 7
  • 17
  • 1
    node is a javascript runtime environment. It doesn't use any ports it just executes javascript code on the machine. What uses the port is the web server that may or may not run in that environment. – trixn Apr 25 '21 at 14:13
  • 2
    Sure, but he is using express with node. I ment that express needs a port. Thank you for pointing that out, I have now edited my answer. – Sylvain Apr 25 '21 at 14:14
  • Well you wrote that node serves on port 5000 and react serves on port 3000 but in fact non of those serve anything on any port. What you probably mean is an express js web server that serves the production bundle and maybe the development web server that is bundled with create-react-app? – trixn Apr 25 '21 at 14:16
1

If you want your Express ejs pages to serve your React code on the same port create the following files:

src/javascripts/views/layout.ejs:

<!DOCTYPE html>
<html lang="en">
<head>
  <title><%= title %></title>
</head>
<body>
    <div class="container" >
        <h2>Server rendered EJS File</h2>
        <div id="main">
           <!--This div is where React Component Renders -->
        </div> 
    </div>
    <script src="javascripts/main.js"></script>
</body>
</html>

src/javascripts/main.js file:

import React from 'react'
import ReactDOM from 'react-dom'

import App from './components/App'

ReactDOM.render(<App />, document.getElementById('main'))

src/javascripts/components/App.js

import React from 'react'

export default function App() {
    return (
        <div className="react-stuff">
            <h1>My React App component</h1>            
        </div>
    )
}

In your Express server designate the following public folder:

app.use(express.static(path.join(__dirname, 'public')))

In webpack specify that your React source code should compile from src/javascripts/main.js to pubic/javascripts/main.js:

  entry: {
    main: './src/javascripts/main.js'
  },
  output: {
    path: path.resolve(__dirname, 'public'),
    filename: 'javascripts/main.js',
    publicPath: '/'
  },

Finally, create an Express route that serves layout.ejs. Say "/" (e.g. http://localhost:8080)

Now, every time you compile your React code it will take the code in ./src/javascripts/main.js and compile/bundle it to your Express static directory (e.g. public/javascripts/main.js)

And when you request http://localhost:8080, Express will serve layout.ejs. Since layout.ejs is connected to your React bundle via the script tag which points to public/javascripts/main.js it will serve your App.js React component!

Note: The above solution is relying on an architecture where your React pages are going to be served by Express. However, if you want to create a SPA (a single page application) that is completely independent of your Express server (except perhaps for the SPA's API calls) then the solution will be different and will involve (as other answers have suggested) the use of a proxy line in your package.json.

Here also is a diagram that outlines the relationship between the different files:

enter image description here

Luke
  • 2,751
  • 1
  • 17
  • 20
  • It's also helpful to have repos that actually demo these different solutions (e.g. a SPA approach versus ejs files serving React components) because they also rely on configuration settings in package.json and webpack.config.js . So setting things up without a working repo/example might be a little challenging. Especially if you are just used to working with React's default dev ecosystem (e.g. create-react-app). Perhaps the community can point you to some repos.... – Luke Apr 25 '21 at 16:10
0

Well, it's senseless to have same port for different server. However, you want to replace ejs and use react inside node server, then you can host the project in single port. But it will be difficult for everyone, the developer, the users.

So, use different project directory for serving client and the server. If you are facing some issue with the connection to the database, and feeling the one port is only working, you can change the port for them.

However, I think this post should help you to connect mongodb?

Bhojendra Rauniyar
  • 83,432
  • 35
  • 168
  • 231
0

Instead of going with the traditional create-react-app approach, you can create your own Webpack + Babel configurations in your client directory.

I created a repo recently that demonstrates it: https://github.com/codingjlu/express-react-template. The entire server is powered by Express and once you save files in the client directory it re-compiles your app to the public directory. To use it with EJS just remove the Html Webpack Plugin and the hash. Here's what the config should look like:

const path = require('path');

module.exports = {
  entry: path.resolve(__dirname, 'src/index.js'),
  devtool: 'inline-source-map',
  watch: true,
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
    publicPath: '/'
  },
  module: {
    rules: [
      {
        test: /\.js|\.jsx$/,
        exclude: /node_modules/,
        include: path.resolve(__dirname, 'src'),
        use: ["babel-loader"]
      }
    ]
  }
}

Then add your EJS file to client/dist/myFile.ejs and link the bundle inside:

<script src="/bundle.js"></script>

It should work perfectly.

code
  • 5,690
  • 4
  • 17
  • 39