Connect express with react application - javascript

I want to create simple react app with express server.
I have setup simple express server like following.
package.json
{
"name": "hometask1",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^8.0.4",
"babel-preset-env": "^1.7.0",
"eslint": "^5.9.0",
"eslint-loader": "^2.1.1",
"express": "^4.16.4",
"jest": "^23.6.0",
"npm-run-all": "^4.1.3",
"open": "0.0.5",
"webpack": "^4.26.0",
"webpack-dev-middleware": "^3.4.0",
"webpack-hot-middleware": "^2.24.3"
},
"proxy": "http://localhost:3000/"
}
index.js
const express = require('express')
const app = express()
const port = 3000
//app.get('/', (req, res) => res.send('Hello World!'))
app.listen(port, () => console.log(`Listening on port ${port}!`))
app.get('/express_backend', (req, res) => {
res.send({ express: 'YOUR EXPRESS BACKEND IS CONNECTED TO REACT' });
});
I have folder structure like:
projectfolder
node_modules
index.html
index.js
package.json
package-lock.json
Now, i want to connect this express.js with my react app. Following is my react app. (I don't want to use create-react-app)
index.html
<!DOCTYPE html>
<html>
<head>
<title>Hello React</title>
<script src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone#6.15.0/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
</body>
<script type="text/babel">
var helloWorld = React.createElement("h1", {}, 'Hello World!');
class HelloWorld extends React.Component {
render () {
return (
<h1>Hello World!</h1>
)
}
}
const container = React.createElement("div", {}, helloWorld, <HelloWorld /> );
ReactDOM.render(container, document.getElementById('root'))
</script>
</html>
Any help would be greatly appreciated.

You need to serve your files from a public dir on base URL request (http://domain/)
1. Make css, jss files publicly accessible
Add this line to your express server file
const app = express()
const port = 3000
app.use(express.static('public')) // this line
2. Move index.html and index.js to public dir
You dir structure will look like
projectfolder
node_modules
public
index.html
index.js
package.json
package-lock.json
3. Add a route to serve the index file
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname + '/public/index.html'));
});

Related

With Vue app, when serving client from within the server directory and hosting my app, I'm unable to fetch data getting JS enabled error

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"
}
}

reactjs expressjs how to setup proxy? proxy doesn't work with localhost:3000, but works with localhost:3000/test

Trying to work with reactjs (create-react-app) and now including expressjs. What I've done is
move my folder/* to folder/client/* (deleting node_modules)
cd folder/client/ and npm install to recreate the node_modules
*it works as before, the app renders well
cd folder and npm init
npm install express --save
write the folder/server.js
add the proxy settings in /folder/client/package.json
npm run start in /folder and in /folder/client
Then, I go to localhost:3000 and I get the reactjs app, without express anywhere. Then I go to localhost:8080 and I get the express result, which is indeed the same page as before but without being executed by react (nothing wrong here, I assume)
And then I go to localhost:3000/test and it gets proxied to express, where I see in the terminal the console.log of server.js
So I cannot proxy localhost:3000, but I can localhost:3000/whatever. What is wrong?
server.js
const express = require('express');
const path = require('path'); // haven't installed, should I?
const app = express();
app.use(express.static(path.join(__dirname, 'build'))); // of no use here
app.get('/ping', function (req, res) { // this one works
return res.send('pong');
});
// app.get('', function (req, res) { // doesn't work
// app.get('*', function (req, res) { // doesn't work
// app.get('.', function (req, res) { // doesn't work
// app.get('.*', function (req, res) { // doesn't work
// app.get('./', function (req, res) { // doesn't work
app.get('./*', function (req, res) { // doesn't work
console.log('hey') // never seen
res.sendFile(path.join(__dirname, 'client/src', 'index.html'));
});
app.get('/test', function (req, res) { // this one works
console.log('hey2') // I do see this when calling localhost:3000/test
res.sendFile(path.join(__dirname, 'client/src', 'index.html'));
});
app.listen(process.env.PORT || 8080);
package.json (/)
{
"name": "ouyea",
"version": "0.1.1",
"description": "This project was bootstrapped with [Create React App](https://github.com/facebookincubator/create-react-app).",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node server.js"
},
"repository": {
"type": "git",
"url": "git+https://xxxx"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://xxxx"
},
"homepage": "https://xxxx",
"dependencies": {
"express": "^4.16.4"
}
}
package.json (/client)
{
"name": "client",
"version": "0.1.1",
"private": true,
"dependencies": {
"axios": "^0.18.0",
"googleapis": "^33.0.0",
"papaparse": "4.6.0",
"react": "^16.4.2",
"react-dom": "^16.4.2",
"react-scripts": "1.1.4",
"semantic-ui-css": "^2.4.0",
"semantic-ui-react": "^0.82.5"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"proxy": {
"": { // I know comments don't work, but I put them here for clarity, none of them worked
// "*": {
// ".": {
// "/": {
"target": "http://localhost:8080"
},
"/test": {
"target": "http://localhost:8080"
}
}
}
The purpose of the express server is to simply a) render the base HTML page from your dist folder, and b) supply data from endpoints that you set up as routes in Express which can be accessed by your React client application. There are apps (universal) that can render React pages from Express but that's not what you're doing here with create-react-app.

Next Js & Babel causing infinite loop

So I got things working where it babel compiles everything, including next.js
I followed next.js docs on how to handle babel and created a .babelrc file:
{
"presets": ["next/babel", "es2015", "stage-0"]
}
When I run yarn run dev everything compiles and the server starts. When I load a page, next.js will run it's build process. Since things in the directory change, nodemon restarts the server and causes an infinite loop. Can some help me with this please???
This is my package.json file:
{
"name": "creatorsneverdie",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"dev": "nodemon app.js --exec babel-node --ignore node_modules, .next, yarn.lock",
"build": "next build",
"start": "NODE_ENV=production node app.js"
},
"dependencies": {
"axios": "^0.16.2",
"bcrypt": "^1.0.2",
"body-parser": "^1.17.2",
"cors": "^2.8.4",
"cryptr": "^2.0.0",
"dotenv": "^4.0.0",
"express": "^4.15.3",
"express-session": "^1.15.4",
"lodash": "^4.17.4",
"lowdb": "^0.16.2",
"next": "^2.4.7",
"passport": "^0.3.2",
"passport-jwt": "^2.2.1",
"react": "^15.6.1",
"react-dom": "^15.6.1"
},
"devDependencies": {
"babel-cli": "^6.24.1",
"babel-loader": "^7.1.1",
"babel-preset-es2015": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"nodemon": "^1.11.0"
}
}
And the app.js file:
import express from 'express'
import session from 'express-session'
import bodyParser from 'body-parser'
import cors from 'cors'
import passport from 'passport'
const db = require('./db/index.js').initDb()
const writeSeeds = require('./db/index.js').writeSeeds
const routes = require('./routes/index')
require('dotenv').config({path: 'variables.env'});
// Next config
const next = require('next')
const dev = process.env.NODE_ENV !== 'production'
const nextLoader = next({dev})
const handle = nextLoader.getRequestHandler()
nextLoader.prepare().then(() => {
const app = express();
app.use(cors());
app.set('db', db);
app.nextRender = nextLoader
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(session({
secret: process.env.SECRET,
resave: false,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
require('./config/passport')(passport);
app.use('/', routes)
app.get('*', (req, res) => {
return handle(req, res)
})
// START APP
app.set('port', process.env.PORT || 1337);
if(!db.has('products').value()) {
writeSeeds(db);
}
const server = app.listen(app.get('port'), () => {
console.log(`Express running -> ${server.address().port}`)
});
})
I was having the same problem and I fixed that by adding "pages/"* to nodemon's ignore list. Somehow the build process is doing the pages source rewrite without changing anything which is then causing nodemon to restart and triggers the rebuild again.
Try to change your dev script to:
nodemon -w app.js --exec babel-node

Express server serves my static files but does not handle requests to my API. What is happening?

I built a small app on top of a company's API. I created my own API to interact with their's. My app uses React-Create-App to scaffold, with Redux, and the server is Experss/Node.js. It works totally fine on localhost but when I deploy it on Heroku, it serves the bundle but doesn't hand any user http requests to the server. It returns a 404 not found. Heroku gives no errors in their logs.
My post install script runs the build, which bundles the app. I have set environment port variable in the heroku dashboard as well.
package.json
{
"name": "event.me",
"version": "0.1.0",
"private": true,
"engines":{
"node": "7.2.1",
"npm": "3.10.10"
},
"dependencies": {
"axios": "^0.15.3",
"body-parser": "^1.17.1",
"express": "^4.15.2",
"moment": "^2.18.1",
"react": "^15.4.2",
"react-dom": "^15.4.2",
"react-progressbar.js": "^0.2.0",
"react-redux": "^5.0.3",
"react-router": "^3.0.0",
"react-router-dom": "^4.0.0",
"redux": "^3.6.0",
"redux-logger": "^3.0.0",
"redux-thunk": "^2.2.0"
},
"devDependencies": {
"eslint": "^3.18.0",
"eslint-config-airbnb": "^14.1.0",
"eslint-plugin-jsx-a11y": "^4.0.0",
"eslint-plugin-react": "^6.9.0",
"eslint-plugin-import": "^2.2.0",
"nodemon": "^1.11.0",
"react-scripts": "0.9.5"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject",
"server": "node server/server.js",
"postinstall": "npm run build"
}
}
server.js file
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const routes = require('./routes');
const app = express();
app.use(express.static(path.resolve(__dirname, '..', 'build')));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use('/api', routes);
const port = process.env.PORT || 8080;
app.listen(port, () => console.log(`Listening on ${port}`));
routes.js
const routes = require('express').Router();
const users = require('./controllers/users.js');
const events = require('./controllers/events.js');
routes.post('/sigin', users.signin);
routes.post('/signup', users.signup);
routes.get('/events', events.getAll);
routes.post('/events', events.attendEvent);
routes.delete('/events', events.flakeEvent);
routes.patch('/events', events.updateEvent);
routes.delete('/singleevent', events.deleteEvent);
routes.post('/createevent', events.createEvent);
module.exports = routes;
If you are using Create React App, one of the things you must do if you want Webpack to be used as proxy when calling your API is to set in your package.json:
...
"proxy": "http://localhost:3030",
...
Thus you use Webpack included in Create React App to proxy all the calls to your API and do not need an extra server.
For Heroku deployment you need to change localhost for Heroku URL and 3030 for your established port in Express server (process.env.PORT).
That's where I think the problem lies.
Also, you have to route your non API petitions to your index.html.
Add this to your server.js.
app.get('*', (req, res) => {
const way = path.join(__dirname, 'build', 'index.html');
res.sendFile(way);
});

React.js SyntaxError: Unexpected token <

I'm really new in react.js. I'm develop in Webstorm.
I have this error and I'm not succeed to solve it, it looks like the react is not recognize but i try to install any npm react package and is still not work..
SyntaxError: Unexpected token <
this is my code:
index.jsx:
/** #jsx React.DOM */
var React = require('react');
var ReactDOMServer = require('react-dom');
var DefaultLayout = require('./layout/Master');
//var element = React.createElement('div', null, 'Hello World!');
//console.log(ReactDOMServer.renderToString(element));
var CommentBox = ReactDOMServer.createClass({
render: function() {
return (
<div>
<h1>aslkdjaslkdj</h1>
</div>
//React.createElement('div', null, 'Hello World!')
);
}
});
module.exports = CommentBox;`var express = require('express');
index.js:
var express = require('express');
var router = express.Router();
var request = require('request');
router.get('/', function (req, res) {
//res.send("<h1> asdasasd </h1>");
res.render('index', {});
});
module.exports = router;
app.js:
var app = express();
var routes = require('./routes/index');
var path = require('path');
app.use('/', routes);
app.set('port', process.env.PORT || '5000');
// view engine setup
app.set('views', path.join(__dirname, '/views'));
app.set('view engine', 'jsx');
app.engine('jsx', require('express-react-views').createEngine());
app.use('/', routes);
module.exports = app;
var server = app.listen(app.get('port'), function(){
console.log("app started");
});`
package.json:
{
"name": "nodewithreactwithjsx",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Almog.h",
"license": "ISC",
"dependencies": {
"babel-preset-es2015": "^6.6.0",
"babel-preset-react": "^6.5.0",
"babel-register": "latest",
"express": "^4.13.4",
"express-react-views": "latest",
"react": "^15.0.2",
"react-dom": "^15.0.2"
},
"devDependencies": {
"babel-core": "^6.8.0",
"babel-loader": "^6.2.4",
"babel-preset-es2015": "^6.6.0",
"babel-preset-react": "^6.5.0",
"react": "^15.0.2",
"react-dom": "^15.0.2",
"webpack": "^1.13.0"
}
}
I think it is because your code has JSX - i.e. the HTML inside JavaScript part of CommentBox
To get JavaScript to run this you need to use a transpiler like Babel - this will turn a statement like:
<div className="apples">hello</div>
Into
React.createElement('div', {className:'apples'}, 'hello')
Javascript engines (like V8 in Chrome) cannot run JSX natively - they need transpiling first. I'm not sure how to get something like babel working in WebStorm though.

Categories