I'm builing a MERN application with create-react-app (so no custom webpack) and a node server. I'm using nodemon to restart changes on the backend, and the problem is that about half of the time it seems that my front-end tries to render before nodemon can restart the node server, resulting in a ECONNREFUSED error.
I can solve the issue my simply refreshing the page, but it's annoying to have to do this repeatedly and I'd like to just figure out what the issue may be. This isn't happening if I run node server instead of nodemon.
Here's the relevant part of my client side package.json:
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"proxy": "http://localhost:7777"
and the server side package.json:
"scripts": {
"client-install": "npm intall --prefix client",
"start": "node server.js",
"server": "nodemon server.js",
"client": "cd client && npm start",
"dev": "concurrently \"npm run server\" \"npm run client\""
}
and my server.js
const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const path = require('path');
const routes = require('./routes/index');
require('dotenv').config();
const app = express();
app.use(bodyParser.json());
mongoose.connect(process.env.DATABASE, {useNewUrlParser: true})
.then(() => console.log('MongoDb connected'))
.catch(err => console.log(`Mongo error ${err}`))
const port = process.env.PORT || 7777;
app.use('/', routes);
if (process.env.NODE_ENV === 'production') {
// Serve any static files
app.use(express.static(path.join(__dirname, 'client/build')));
// Handle React routing, return all requests to React app
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname, 'client/build', 'index.html'));
});
}
app.listen(port, () => {
console.log(`Connected at port ${port}`)
})
I'm using axios for my front-end HTTP requests:
import axios from 'axios';
import FormData from 'form-data'
import keys from '../keys';
export const getPosts = () => {
return axios.get('/api')
}
export const post = (file, bodyInfo) => {
let formData = new FormData();
formData.append('file', file[0], file[0].name);
formData.append('bodyInfo', JSON.stringify(bodyInfo));
return axios.post('/api', formData, {
headers: {
'Content-Type': `multipart/form-data;
boundary=${formData._boundary}`,
}
})
}
export const getSinglePhoto = (id) => {
return axios.get(`/api/${id}`);
}
export const postUser = (userDetails) => {
console.log(userDetails);
return axios.post('/api/user', userDetails)
}
export const getUser = () => {
return axios.get('/user');
}
export const removeUser = (id) => {
return axios.delete(`/user/${id}`)
}
and here are my routes:
router.get('/api', postController.getPosts);
router.post('/api',
postController.type,
postController.uppic,
postController.cloudinary
);
router.get('/api/:id', postController.getSingle);
router.get('/user', userController.getUser);
router.post('/api/user', userController.postUser);
router.delete('/user/:id', userController.removeUser);
Try using
CORS
instead of apackage.json
proxy. I remember having random/intermittent connection issues when I used one. In short: Front-end runs on port3000
andexpress
API runs on5000
. When compiled, both run on5000
andexpress
serves the compiled front-end js and acts like an API.Very similar set up, but no connection problems:
express server package.json
client/package.json (using a sass compiler, which you can use/ignore).
client/src/actions/axiosConfig.js (then I create an
axios
config to automatically point to my Express API running on5000
)client/src/actions/authActions.js (then import the
axios
config)express server.js (I use
consign
to import all the files):However, the equivalent would be: