I am making a MERN app and having some problems with connecting/running node and react server together.
Root package.json
{
"name": "server",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "nodemon server/server",
"client": "npm start --prefix client",
"dev": "concurrently \"npm start\" \"npm run client\""
},
"dependencies": {
"async": "^3.2.0",
"cookie-parser": "~1.4.4",
"debug": "~2.6.9",
"dotenv": "^10.0.0",
"express": "~4.16.1",
"http-errors": "~1.6.3",
"jade": "~1.11.0",
"mongoose": "^5.13.0",
"morgan": "~1.9.1",
"populatedb": "^1.0.0"
},
"devDependencies": {
"concurrently": "^6.2.0",
"nodemon": "^2.0.8"
}
}
Client proxy:
"proxy": "http://127.0.0.1:5000",
"secure": false
Main server file:
require('dotenv').config();
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
const mongoose = require('mongoose');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
// set up mongoose connection
const mongoDB = process.env.DB_STRING;
mongoose.connect(mongoDB, { useNewUrlParser: true, useUnifiedTopology: true });
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:' ));
console.log('Connected');
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
if(process.env.NODE_ENV !== 'development') {
app.get('*', function (req, res) {
res.sendFile(path.resolve(__dirname, 'client/build', 'index.html'));
});
}
const PORT = process.env.PORT || 5000
//Express js listen method to run project on http://localhost:5000
app.listen(PORT, console.log(`App is running in ${process.env.NODE_ENV} mode on port ${PORT}`))
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// 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');
});
module.exports = app;
I am using 'npm run dev' command to start the server.
I am getting an error message "proxy error: could not proxy request /users from localhost:3000 to http://127.0.0.1:5000".
I have tried changing proxy to 0.0.0 and also changed the scripts file to:
"start": "node ./bin/www",
"devstart": "nodemon ./bin/www",
"client": "npm start --prefix client",
"dev": "concurrently \"npm start\" \"npm run client\""
but it still does not work. I have tried some other solutions I've found but just can't get it right.
Here is also my test react file:
import React, { useState, useEffect } from "react";
import axios from "axios";
const App = () => {
const [users, setUsers] = useState([]);
const getData = async () => {
const res = await axios.get("/users");
setUsers(res.data);
};
useEffect(() => {
getData();
}, []);
return (
<div>
{users.map((u) => (
<h4 key={u._id}>userName : {u.full_name}</h4>
))}
</div>
);
};
export default App;
Here is also my folder structure, if it is relevant by any chance
After trying some more solutions to fix the problem, what worked is:
in one terminal tab run nodemon app.js
in second terminal tab run npm start --prefix client.
There is probably something wrong with concurrently module, since this is working.
Related
EDIT: To be clear, this only happening when i'm trying to host the app. Works PERFECT during local environment testing..
When trying to fetch data from my backend getting an error in Chrome saying that JS is not enabled. (IT IS) so that is not the issue..
Thinking there may be an issue with my package.json maybe if the commands are incorrect for use on the host machine? Have tried Render & Heroku same issues.
I had tried to run the commands within my local environment and the app works flawlessly fetching data as intended. Only when hosting the app do I not get any data back from the server when making API call from the front end, instead get JS not enabled error in the Network tab and no errors on Front End that I can see..
Hosted app to see network error: https://elf-invasion.herokuapp.com/
File Structure:
/root
|- config.js
|- server.js
|- package.json + package-lock.json
|- client/
|- vue.config.json
|- ... (rest of dist, src, node_modules, public etc.)
|- models/
|- Elf.js + HighScore.js
|- routes/
|- api/
|- elf.js + highScore.js
config.js
module.exports = {
hostUrl: process.env.HOST_URL,
mongoURI: process.env.MONGO_URI,
PORT: process.env.PORT || 3000,
};
server.js
const express = require("express");
const app = express();
const port = 3000;
const mongoose = require("mongoose");
const { PORT, mongoURI } = require("./config.js");
// routes
const Player = require("./routes/api/player");
const Elf = require("./routes/api/elf");
const HighScore = require("./routes/api/highScore");
// cors is a middleware that allows us to make requests from our frontend to our backend
const cors = require("cors");
// morgan is a middleware that logs all requests to the console
const morgan = require("morgan");
// body-parser is a middleware that allows us to access the body of a request
const bodyParser = require("body-parser");
const path = require("path");
app.use(cors());
// use tiny to log only the request method and the status code
app.use(morgan("tiny"));
app.use(bodyParser.json());
// chek if we are in production
if (process.env.NODE_ENV === "production") {
// check if we are in production mode
app.use(express.static("client/dist"));
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "client", "dist", "index.html"));
});
}
// test if server is running and connected to mongoDB
app.get("/", (req, res) => {
res.send("Hello World!");
});
// app.get("/", (req, res) => {
// res.send("Hello World!");
// });
// use routes
app.use("/api/", Player);
app.use("/api/", Elf);
app.use("/api/", HighScore);
mongoose
.connect(mongoURI, {
useNewUrlParser: true,
useUnifiedTopology: true,
useUnifiedTopology: true,
})
.then(() => console.log("MongoDB connected..."))
.then(() => {
// log uri to console
console.log(`MongoDB connected to ${mongoURI}`);
})
.catch((err) => console.log(err));
app.listen(PORT, () => {
console.log(`Example app listening at ${PORT}`);
});
package.json
{
"name": "week1",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"server": "nodemon server.js --ignore 'client/'",
"client": "npm run serve --prefix client",
"dev": "concurrently \"npm run server\" \"npm run client\"",
"start": "node server.js",
"build": "npm install --prefix client && npm run build --prefix client"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.20.1",
"bootstrap": "^5.2.3",
"cors": "^2.8.5",
"dotenv": "^16.0.3",
"express": "^4.18.2",
"mongoose": "^6.7.5",
"morgan": "^1.10.0",
"portal-vue": "^2.1.7"
},
"devDependencies": {
"concurrently": "^7.6.0",
"nodemon": "^2.0.20"
}
}
I'm trying to deploy my express-generated backend. But I constantly get this failure. I don't know how or why this is happening.
Here is my package.json
{
"name": "backendev",
"version": "0.9.3",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"bcryptjs": "^2.4.3",
"cookie-parser": "~1.4.4",
"cors": "^2.8.5",
"debug": "~2.6.9",
"dotenv": "^10.0.0",
"express": "^4.17.1",
"http-errors": "~1.6.3",
"jade": "~1.11.0",
"morgan": "~1.9.1",
"mysql": "^2.18.1",
},
"devDependencies": {
}
}
And here is my vercel.json.
{
"version": 2,
"builds": [
{
"src": "./app.js",
"use": "#vercel/node"
}
],
"routes": [
{
"src": "/(.*)",
"dest": "./"
}
]
}
I tried adding the uglify-js dependencies and deleting the package-lock.json as someone suggested in another forum, but alas, same problem.
What's happening?
UPDATE: I tried creating an Index.js file just to test how it works on vercel and it did work. It seems to be that something is going on with my app.js that is causing the trouble on vercel
Here's the index.js that I used to test:
const express = require('express');
const app = express();
app.get('/', (req, res) => res.send('Home Page Route'));
app.get('/about', (req, res) => res.send('About Page Route'));
app.get('/portfolio', (req, res) => res.send('Portfolio Page Route'));
app.get('/contact', (req, res) => res.send('Contact Page Route'));
const port = process.env.PORT || 3000;
app.listen(port, () => console.log(`Server running on ${port}, http://localhost:${port}`));
And Here is my app.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 usersRouter = require('./routes/users');
var backendRouter = require('./routes/backend/index')
var corsOptions = {
origin: process.env.CORS_ORIGIN,
optionSuccessStatus: 200
}
var app = express();
//enable cors
if (process.env.ENABLE_CORS == "1"){
app.use(cors(corsOptions));
}
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/backend',backendRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// 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');
});
module.exports = app;
I had a self-inflicted case. i deleted the line
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
in file app.js and it worked. You can try, Good luck!
works locally when i npm run start but fails on heroku. the only error i get on the logs is " This app may not specify any way to start a node process". ive tried changed the scripts. and ive tried to use the create react app documentation. ive also implemented the "https://github.com/mars/create-react-app-buildpack.git" build pack to the project
my file structer
//client
|
+-node modules
+ public
+-src
+-package-lock
+-package.json
//node_modules
//server
|
+-models
+-server.js
+-routes
+-Controllers
+-middlewares
+-config
+-env
+-gitignore
+-nodemon.json
+-package-lock.json
+-package.json
My main package.json scripts
"scripts": {
"start": "npm run start:dev",
"start:prod": "node server/server.js",
"start:dev": "concurrently \"nodemon --ignore 'client/*'\" \"npm run client\"",
"client": "cd client && npm run start",
"seed": "node server/scripts/seedDB.js",
"install": "cd client && npm install",
"build": "cd client && npm run build",
"heroku-postbuild": "npm run build"
},
my server.js
require('dotenv').config();
const express = require('express');
const morgan = require('morgan');
const session = require('express-session');
const MongoStore = require('connect-mongo')(session);
const dbConnection = require('./config/connection');
const passport = require('./config/passport');
const path = require('path');
const app = express();
const PORT = process.env.PORT || 8090;
// Middlewares
app.use(morgan('dev'));
app.use(express.urlencoded({extended: false}));
app.use(express.json());
app.use('/', express.static(path.join(__dirname, '../client/build')));
// Passport
app.use(passport.initialize());
app.use(passport.session()); // will call the deserializeUser
app.use(session({
secret: 'my_secret', // process.env.AUTH_SECRET,
store: new MongoStore({ mongooseConnection: dbConnection }),
resave: false,
saveUninitialized: false
}));
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, '../client/build/'))
});
// Add Auth and API routes
app.use('/auth', require('./routes/authRoutes'));
app.use('/api', require('./routes/apiRoutes'));
// If no routes are hit, send the React app
app.use(function(req, res) {
res.sendFile(path.join(__dirname, '../../client/build/index.html'));
});
// Error handler
app.use(function(err, req, res, next) {
console.error(err.stack);
res.status(500);
})
app.listen(PORT, () => {
console.log(`App listening on PORT: ${PORT}`);
});
It seems like you haven't added a Procfile. If not in the root directory of your node API add a file called Procfile with no extensions i.e .js. Once you have made the file add the following line :
web: npm run start.
I am new to node js and following a tutorial on scotch.io. I've imported morgan for logging requests, but when I run the code I get TypeError: app.use is not a function. This is my code for app.js;
const express = require('express');
const logger = require('morgan');
const bodyParser = require('body-parser');
const app = express;
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.get('*', (req, res) => res.status(200).send({
message: 'Welcome to deep thinking.'
}));
module.exports = app;
And for package.json:
{
"name": "postgres-express-react-node-tutorial",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start:dev": "nodemon ./bin/www",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.18.3",
"express": "^4.16.3",
"morgan": "^1.9.1"
},
"devDependencies": {
"nodemon": "^1.18.4"
}
}
require('express') returns a function, which you should call in order to get the express application. Therefore:
const app = express;
should be changed to:
const app = express();
Try this, change app=express; to app=express();
const express = require('express');
const logger = require('morgan');
const bodyParser = require('body-parser');
const app = express(); // changed this line
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.get('*', (req, res) => res.status(200).send({
message: 'Welcome to deep thinking.'
}));
module.exports = app;
I want to upload file from postman to node js but I have problem.
POSTMAN
Write url,check post method,check form-data,check file,write file name and choose file
This is my code
app.js
const express = require('express');
const bodyParser = require('body-parser');
const fileUpload = require('express-fileupload');
app.use(fileUpload());
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
router.js
router.post('/schedule/entry', function(req,res){
console.log(req.file.name);
});
Console return me undefined name, if I write this code
router.post('/schedule/entry', function(req,res){
console.log(req.file);
});
Return 'undefined'
Why?
package.json
{
"name": "nodejs-rest-api-authentication",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"start": "node server.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"bcryptjs": "^2.4.3",
"body-parser": "^1.16.1",
"csv-array": "0.0.22",
"csv-write-stream": "^2.0.0",
"express": "^4.14.1",
"express-fileupload": "^0.3.0",
"fast-csv": "^2.4.1",
"formidable": "^1.1.1",
"json2csv": "^3.11.5",
"jsonwebtoken": "^8.1.0",
"mysql": "^2.15.0"
}
}
server.js
const app = require('./app');
const port = process.env.PORT || 3000;
const server = app.listen(port, function() {
console.log('Server listening on port ' + port);
});
screenshots
screenshots
codeGit
Based on the discussion in the comment section:
const express = require('express')
const app = express()
const formidable = require('formidable')
const path = require('path')
const uploadDir = '' // uploading the file to the same path as app.js
app.post('/', (req, res) =>{
var form = new formidable.IncomingForm()
form.multiples = true
form.keepExtensions = true
form.uploadDir = uploadDir
form.parse(req, (err, fields, files) => {
if (err) return res.status(500).json({ error: err })
res.status(200).json({ uploaded: true })
})
form.on('fileBegin', function (name, file) {
const [fileName, fileExt] = file.name.split('.')
file.path = path.join(uploadDir, `${fileName}_${new Date().getTime()}.${fileExt}`)
})
});
app.listen(3000, () => console.log('Example app listening on port 3000!'))
Attached Screenshots:
Because of body-parser middleware file will be not available in req so you must use another middleware libraries like connect-busboy or multer or connect-multiparty