Problems with proxy server in react app with node.js express - node.js

I have simple express server in server.js
const express = require('express');
const app = express();
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Listening on port ${port}`));
app.get('/express_backend', (req, res) => {
res.send({ "express":"have data"});
});
also component
import { Component } from "react";
import './../css/Rings.css'
import SellItem from "./sellItem";
import Fotter from "./fotter";
class Necklase extends Component{
state ={
data: null
};
componentDidMount() {
this.callBackendAPI()
.then(res => this.setState({ data: res.express }))
.catch(err => console.log(err));
}
callBackendAPI = async () => {
const response = await fetch('/express_backend');
const body = await response.json();
console.log(body.express)
if (response.status !== 200) {
throw Error(body.message)
}
return body;
};
render(){
return <div >
<div className="main">
<SellItem/>
</div>
{this.state.data}
<Fotter/>
</div>
}
}
export default Necklase
when i start my react app with npm start in package json npm start looks like this now, also it is proxy
"start": "react-scripts start",
"proxy": "http://localhost:5000",
and after it i start server.js with node server.js in cmd everything work fine, i can get data from response and display it but if i change "start" to this
"start": "react-scripts start && nodemon server.js ",
i got this error in console
Proxy error: Could not proxy request /express_backend from localhost:3000 to http://localhost:5000/.
See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNREFUSED).
and this when i console.log(body.express) in callBackendAPI
SyntaxError: Unexpected token P in JSON at position 0

can you try with this way
"scripts": {
"start": "nodemon --exec babel-node ./app.js",

Related

Deploy Nextjs App to Cpanel Subdomain Not Working

So I followed a tutorial on how to deploy NextJs app to a subdomain on a Cpanel hosting by adding a server.js file and modifying the Package.json file with the following:
// server.js
const { createServer } = require('http')
const { parse } = require('url')
const next = require('next')
const dev = process.env.NODE_ENV !== 'production'
const hostname = 'localhost'
const port = process.env.port || 3000
// when using middleware `hostname` and `port` must be provided below
const app = next({ dev, hostname, port })
const handle = app.getRequestHandler()
app.prepare().then(() => {
createServer((req, res) => {
// Be sure to pass `true` as the second argument to `url.parse`.
// This tells it to parse the query portion of the URL.
const parsedUrl = parse(req.url, true)
const { pathname, query } = parsedUrl
if (pathname === '/a') {
app.render(req, res, '/a', query)
} else if (pathname === '/b') {
app.render(req, res, '/b', query)
} else {
handle(req, res, parsedUrl)
}
}).listen(port, (err) => {
if (err) throw err
console.log(`> Ready on http://${hostname}:${port}`)
})
})
//Package.json file
...
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "NODE_ENV=production node server.js",
"lint": "next lint",
"json-server": "json-server --watch db.json --port 3004"
}
...
I run npm build and uploaded the files to a folder that points to a subdomain. However, when I create my application in Node.js in Cpanel, the "Run NPM Install" button is greyed out and the information I keep getting is that the package.json cannot be found in the folder meanwhile it is actually there.
Any help on what could be wrong or a link to a better tutorial?
Your application root name should be the same with the application url.
Also ensure you uploaded all your file inside your application root name.
The components needed are the .next/ directory and files next.config.js, package.json and server.js, package-lock.json
Click Stop app button and refresh page.

How to properly set up Ubuntu 20.04 to deploy a node.js app without caching issues?

I have launched my first node.js app using express.js for the backend and react.js for the frontend. I have it deployed as a background service on a VM with Ubuntu 20.04. The app itself is pretty simple. It makes an API call, gets the latest data and displays it to the enduser in a web browser interface. I initially deployed it on a free Heroku account, where it works fine and always display the latest info from the API call. But when I deployed it on a private VM with Ubuntu 20.04, I noticed that it does not show the latest API info anymore, i.e. it makes the initial API call during npm start and then probably caches it on the server. So, if I come to the app the next day, all the data is from yesterday. To see the latest data, I have to kill the background service on Ubuntu and then do "npm start", which starts the server and makes the API call. I then see the latest data in the browser. This is my first time working with all this technology, so if you have had a similar issue with deploying on Ubuntu, please let me know how I can fix it.
Here is my package.json "scripts":
"scripts": {
"start:dev": "nodemon --exec babel-node server/server.js --ignore public/",
"build": "babel server --out-dir dist",
"start": "node dist/server.js &",
"dev": "webpack -w --mode=development",
"prod": "webpack --mode=production"
}
Here is my server.js code:
import config, { nodeEnv, logStars } from "./config";
import apiRouter from "./api";
import sassMiddleware from "node-sass-middleware";
import path from "path";
import AMdataPullDone from "./AMdataPullDone";
import express from "express";
const server = express();
server.use(
sassMiddleware({
src: path.join(__dirname, "sass"),
dest: path.join(__dirname, "public"),
})
);
server.set("view engine", "ejs");
server.get("/", (req, res) => {
AMdataPullDone.then(({ initialMarkup, initialData }) => {
res.render("index", {
initialMarkup,
initialData,
});
}).catch(console.error);
});
server.use("/api", apiRouter);
server.use(express.static("public"));
server.listen(config.port, config.host, () => {
console.info("Express listening on port ", config.serverUrl);
});
And here is my index.js file with the reach App:
import React from "react";
import ReactDOM from "react-dom";
import App from "./components/App";
ReactDOM.hydrate(
<App initialData={window.initialData} />,
document.getElementById("root")
);
AMdataPullDone.js code:
import React from "react";
import ReactDOMServer from "react-dom/server";
import App from "./src/components/App";
import generateToken from "./utils/generateToken";
import serverGetAMData from "./serverGetAMData";
const AMdataPullDone = new Promise((resolve, reject) => {
generateToken()
.then(({ access_token }) => {
serverGetAMData(
access_token,
"URL_to_external_API"
)
.then((segResult) => {
const allData = {
initialMarkup: ReactDOMServer.renderToString(
<App initialData={segResult} />
),
initialData: segResult,
};
return resolve(allData);
})
.catch((err) => {
return reject(err.response);
});
})
.catch(console.error);
});
export default AMdataPullDone;
serverGetAMData.js code:
import axios from "axios";
import config from "./config";
const serverGetAMData = async (access_token, apiUrl) => {
const folders = [];
await axios
.get(apiUrl, {
headers: {
Authorization: `Bearer ${access_token}`,
"x-api-key": config.AM_IMS_client_id,
"x-gw-ims-org-id": config.org_id,
}
})
.then((resp) => {
folders.push(...resp.data);
//return resp.data;
})
.catch(console.error);
return folders;
};
export default serverGetAMData;

API Koa server in the backend for Nuxt doesn't run on Heroku (production)

I'm running Nuxt in Universal Mode with Koa as API / Controller in the backend based on the Koa template. I'm deploying to Heroku. API works fine locally, but returns 404 in production. I think that the app is running as SPA when deployed as everything else works well.
Here's my server/index.js
const Koa = require('koa')
const consola = require('consola')
const Router = require('koa-router');
const { Nuxt, Builder } = require('nuxt')
const api = require('./api');
console.log('server works'); // ------> This line gets ignored by the Heroku console
const app = new Koa()
const router = new Router();
// Import and Set Nuxt.js options
const config = require('../nuxt.config.js')
config.dev = app.env !== 'production'
router.use('/api', api.routes(), api.allowedMethods());
app.use(router.routes());
async function start () {
// Instantiate nuxt.js
const nuxt = new Nuxt(config)
const {
host = process.env.HOST || '127.0.0.1',
port = process.env.PORT || 3000
} = nuxt.options.server
// Build in development
if (config.dev) {
const builder = new Builder(nuxt)
await builder.build()
} else {
await nuxt.ready()
}
app.use((ctx) => {
ctx.status = 200
ctx.respond = false // Bypass Koa's built-in response handling
ctx.req.ctx = ctx // This might be useful later on, e.g. in nuxtServerInit or with nuxt-stash
nuxt.render(ctx.req, ctx.res)
})
app.listen(port, host)
consola.ready({
message: `Server listening on http://${host}:${port}`, // ------> Neither this line appears in Heroku console
badge: true
})
}
start()
Procfile
web: nuxt start
Scripts from package.json
"scripts": {
"dev": "cross-env HOST=192.168.1.65 NODE_ENV=development nodemon server/index.js --watch server ",
"build": "nuxt build",
"start": "cross-env NODE_ENV=production node server/index.js",
"generate": "nuxt generate",
"test": "ava",
"test:unit": "cross-env TEST=unit ava --config unit.config.js",
"test:e2e": "cross-env TEST=e2e ava --config e2e.config.js",
"heroku-postbuild": "nuxt build"
}
I think I'm getting nu(x)ts after reading all these deployment docs and not seeing the obvious.
Thanks.
I didn't live any problem, attaching my package.json, server/index.js file and Heroku environment settings. You can check herokuapp from here
package.json
{
"name": "testkoa",
"version": "1.0.0",
"description": "My first-class Nuxt.js project",
"author": "Ahmet Zeybek",
"private": true,
"scripts": {
"dev": "cross-env NODE_ENV=development nodemon server/index.js --watch server",
"build": "nuxt build",
"start": "cross-env NODE_ENV=production node server/index.js",
"generate": "nuxt generate"
},
"dependencies": {
"#nuxtjs/axios": "^5.3.6",
"#nuxtjs/dotenv": "^1.4.0",
"#nuxtjs/pwa": "^3.0.0-0",
"cross-env": "^5.2.0",
"koa": "^2.6.2",
"koa-router": "^7.4.0",
"nuxt": "^2.0.0"
},
"devDependencies": {
"nodemon": "^1.18.9"
}
}
server/index.js
const Koa = require("koa");
const Router = require("koa-router");
const consola = require("consola");
const { Nuxt, Builder } = require("nuxt");
const app = new Koa();
// Import and Set Nuxt.js options
const config = require("../nuxt.config.js");
config.dev = app.env !== "production";
async function start() {
app.use(async function handleError(ctx, next) {
try {
await next();
} catch (err) {
ctx.status = err.statusCode || err.status || 500;
ctx.body = err;
}
});
const router = new Router({ prefix: "/api" });
router.get("/:name", async ctx => {
ctx.response.body = `Hello ${ctx.params.name}`;
});
// Instantiate nuxt.js
const nuxt = new Nuxt(config);
const {
host = process.env.HOST || "127.0.0.1",
port = process.env.PORT || 3000
} = nuxt.options.server;
// Build in development
if (config.dev) {
const builder = new Builder(nuxt);
await builder.build();
} else {
await nuxt.ready();
}
app.use(router.routes());
app.use(router.allowedMethods());
app.use(ctx => {
ctx.status = 200;
ctx.respond = false; // Bypass Koa's built-in response handling
ctx.req.ctx = ctx; // This might be useful later on, e.g. in nuxtServerInit or with nuxt-stash
nuxt.render(ctx.req, ctx.res);
});
app.listen(port, host);
consola.ready({
message: `Server listening on http://${host}:${port}`,
badge: true
});
}
start();
Heroku Config Vars
HOST=0.0.0.0
NODE_ENV=production
NPM_CONFIG_PRODUCTION=false
You don't need Procfile to use your Nuxt app on Heroku with this
configuration, remove it from your project folder

Vue: Proxy requests to a separate backend server with vue-cli

I am using vue-cli webpack template to generate my projects, and I'd like to proxy requests to a separate, backend server. But I got the error message as follow.
Could anyone tell me what's the matter with my coding?
Thank you very much!
Error message
[HPM] Error occurred while trying to proxy request from localhost:8080 to http://localhost:3000 (ECONNREFUSED) (https://nodejs.org/api/errors.html#errors_common_system_errors)
config -> index.js
proxyTable: {
'/api':{
target: 'http://localhost:3000',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
src -> main.js
import Vue from 'vue'
import App from './App'
import VueRouter from 'vue-router'
import routerConfig from './router.config.js'
import Axios from 'axios'
Vue.config.productionTip = false;
Vue.prototype.$axios = Axios;
Vue.prototype.HOST = '/api';
Vue.use(VueRouter);
const router = new VueRouter(routerConfig)
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>',
})
src -> App.vue
export default{
created(){
var url = this.HOST
this.$axios.get(url,{
}).then((res)=>{
console.log(res.data)
},(res)=>{
alert(res.status)
})
}
}
server
const express = require('express');
const mysql = require('mysql');
const db = mysql.createPool({
localhost:'localhost',
user:'root',
password:'123456',
database:'blog'
})
const server = express();
server.use('/api',(req,res)=>{
db.query(`SELECT * FROM articles_table`,(err,data)=>{
if(err){
console.error(err);
res.status(500).send('database error').end();
}else{
res.send(data)
}
})
})
server.listen(3000)
Do as follows:
npm install --save-dev concurrently
Add to scripts at package.json:
"server": "node server.js",
"go": "concurrently --kill-others \"npm run dev\" \"npm run server\""
And use, from now on:
npm run go
Naturally, you can rename go to whatever you want.

Troubleshoot Resolving Express-GraphQL Endpoint with Apollo Client and Proxy Config

I'm attempting to connect to an Express-GraphQL endpoint in a Create-React-App using Apollo Client with a custom proxy config for development. I receive the following error: .
Apollo Client Network Interface:
import {ApolloProvider, ApolloClient, createNetworkInterface} from 'react-apollo';
import './index.css';
const client = new ApolloClient({
networkInterface: createNetworkInterface({
uri:"http://localhost:8080/graphql",
}),
connectToDevTools: true
});
Express Server / GraphQL Server
const graphqlHTTP = require('express-graphql');
const app = express();
app.use('/graphql', graphqlHTTP(request =>{
return {
schema: schema,
graphiql: true,
rootValue: root
} }));
let server;
function runServer(dbUrl, host, port=3001) {
return new Promise((resolve, reject) => {
mongoose.Promise = global.Promise;
mongoose.connect(dbUrl, err => {
if (err) {
return reject(err);
}
server = app.listen(port, host, () => {
console.log(`Your app is listening on port ${port}`);
resolve();
})
The Proxy
(With http-proxy-middlewear)
const express = require('express');
const proxy = require('http-proxy-middleware');
const app = express();
const runServer = require('./server').runServer;
const app = express();
// Proxy everything through to Create React App
app.use(proxy('http://localhost:3000/', {
logLevel: 'warn', // Keep the logs clean
ws: true, // Proxy websockets too
router: {
// Anything to /api goes to our backend
'http://localhost:8080/graphql': 'http://localhost:3001/',
}
}));
app.listen(8080);
Top Level package.json aka The Reason
(3 package.json's for client, server, and top level)
"scripts": {
"start": "node index.js",
"heroku-postbuild": "cd client && npm install --only=dev && npm run build",
"dev": "run-p dev:server dev:client start",
"dev:client": "cd client && cross-env BROWSER=none npm start -- --color=always | xp http://localhost:3000/ http://localhost:8080/",
"dev:server": "cd server && npm start",
"install": "run-s install:server install:client",
"install:server": "cd server && npm install",
"install:client": "cd client && npm install"
},

Resources