How to do server side rendering with node reactjs? - node.js

I have created a sample project in reactjs and using node for backend. I have build react project with webpack. Now I want to render my react app from the server-side but got stuck with an error:
const express = require('express');
const path = require('path');
const logger = require('morgan');
const bodyParser = require('body-parser');
const cors = require('cors');
const { renderToString } = require("react-dom/server");
const { StaticRouter } = require("react-router-dom")
const React = require("react");
const App = require('./src/App')
const session = require('express-session');
const routes = require('./server/index');
const port = process.env.PORT || 3000;
const app = express();
app.use(express.static(path.join(__dirname, 'dist')));
app.use(cors());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
//app.use(cookieParser());
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', '*');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET,POST');
// Request headers you wish to allow
res.setHeader(
'Access-Control-Allow-Headers',
'X-Requested-With,content-type',
);
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
// end
app.use('/', routes);
app.use((req, res, next) => {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
if (app.get('env') === 'development') {
app.use((err, req, res, next) => {
res.status(err.status || 500);
res.json({
message: err.message,
error: err,
});
});
}
app.use((err, req, res, next) => {
res.status(err.status || 500);
res.json({
message: err.message,
error: {},
});
});
router.get("*", (req, res) => {
// Render the component to a string.
const html = ReactDOMServer.renderToString(
<StaticRouter location={req.url} context={context}>
<App />
</StaticRouter>
);
const finalDocument =`<html>
<head>
<title>Your App Title</title>
</head>
<body>
<div id="root">${html}</div>
</body>
</html>
`;
res.send(finalDocument);
});
app.listen(port, () => {
console.log('Api Server running on port' + port);
});
module.exports = app;
package.json
{
"name": "ssrnodereact",
"version": "0.1.0",
"private": true,
"dependencies": {
"#material-ui/core": "^4.12.2",
"#material-ui/icons": "^4.11.2",
"#testing-library/jest-dom": "^5.14.1",
"#testing-library/react": "^11.2.7",
"#testing-library/user-event": "^12.8.3",
"body-parser": "^1.19.0",
"cors": "^2.8.5",
"cryptr": "^6.0.2",
"dotenv": "^10.0.0",
"express": "^4.17.1",
"express-session": "^1.17.2",
"formik": "^2.2.9",
"helmet": "^4.6.0",
"morgan": "^1.10.0",
"nodemailer": "^6.6.3",
"path": "^0.12.7",
"pg": "^8.7.1",
"prettier": "^2.3.2",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-ga": "^3.3.0",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",
"typescript": "^4.3.5",
"web-vitals": "^1.1.2",
"yup": "^0.32.9"
},
"scripts": {
"build": "webpack --mode production",
"start": "npm run build && nodemon server.js",
"test": "react-scripts test",
"eject": "react-scripts eject",
"format": "prettier --write ./**/*.{js,jsx,ts,tsx,css,md,json,html} --config ./.prettierrc"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"#babel/core": "^7.15.0",
"#babel/preset-env": "^7.15.0",
"#babel/preset-react": "^7.14.5",
"babel-loader": "^8.2.2",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^3.2.0",
"react-hot-loader": "^4.13.0",
"ts-loader": "^8.3.0",
"webpack": "^4.44.0",
"webpack-cli": "^4.7.2",
"webpack-dev-server": "^3.11.2"
}
}
Got following error:
error
I have tried the following solutions but have not been able to resolve the error:
React Serverside rendering Unexpected token, JSX and Babel

I'm not sure if React is a framework that suits your needs. Server-side rendering can be accomplished much easier and more efficiently using a framework like NextJS.

You can check this plugin and it has examples for you to do the SSR easily.

Related

TypeError: app.address is not a function - Shopify App Node.js

The issue is already describe here
Mocha API Testing: getting 'TypeError: app.address is not a function'
Tried to test my Shopify app using Mocha, Chai created with Nextjs. Tried several workarounds mentioned on the above link. But it still produces the following error
GET requests
GET /customers
1) Success should return true
0 passing (1s)
1 failing
1) GET requests
GET /customers
Success should return true:
TypeError: app.address is not a function
at serverAddress (node_modules\chai-http\lib\request.js:282:18)
at new Test (node_modules\chai-http\lib\request.js:271:53)
at Object.obj.<computed> [as get] (node_modules\chai-http\lib\request.js:239:14)
at Context.<anonymous> (test\appTest.js:44:10)
at processImmediate (node:internal/timers:466:21)
apptest.js
let chai = require("chai");
let chaiHttp = require("chai-http");
const server = require("../server/index");
chai.should();
chai.use(chaiHttp);
describe("GET requests", () => {
describe("GET /customers", () => {
it("Success should return true", (done) => {
chai.request(server)
.get("/customers")
.end((err, res) => {
console.log('Error => ', err);
console.log('Response => ', res);
res.body.success.should.equal(true)
done();
});
});
});
});
server.js
import "#babel/polyfill";
import createShopifyAuth, { verifyRequest } from "#shopify/koa-shopify-auth";
import Shopify, { ApiVersion } from "#shopify/shopify-api";
import dotenv from "dotenv";
import "isomorphic-fetch";
import Koa from "koa";
import Router from "koa-router";
import next from "next";
const mongoose = require("mongoose");
dotenv.config();
const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== "production";
const app = next({
dev,
});
const handle = app.getRequestHandler();
const AccessToken = {};
Shopify.Context.initialize({
API_KEY: process.env.SHOPIFY_API_KEY,
API_SECRET_KEY: process.env.SHOPIFY_API_SECRET,
SCOPES: process.env.SCOPES.split(","),
HOST_NAME: process.env.HOST.replace(/https:\/\/|\/$/g, ""),
API_VERSION: ApiVersion.January22,
//API_VERSION: ApiVersion.October20,
IS_EMBEDDED_APP: true,
// This should be replaced with your preferred storage strategy
SESSION_STORAGE: new Shopify.Session.MemorySessionStorage(),
});
const ACTIVE_SHOPIFY_SHOPS = {};
app.prepare().then(async () => {
const server = new Koa();
const router = new Router();
server.keys = [Shopify.Context.API_SECRET_KEY];
server.use(
createShopifyAuth({
async afterAuth(ctx) {
// Access token and shop available in ctx.state.shopify
const { shop, accessToken, scope } = ctx.state.shopify;
AccessToken["access_token"] = accessToken;
ctx.cookies.set("accessToken", accessToken, {
httpOnly: false,
secure: true,
sameSite: "none",
});
ctx.cookies.set("shop_name", shop, {
secure: true,
sameSite: "none",
httpOnly: false,
});
const host = ctx.query.host;
ACTIVE_SHOPIFY_SHOPS[shop] = scope;
ctx.cookies.set("HOST", host, {
secure: true,
sameSite: "none",
httpOnly: false,
});
//Database Connection
const shopName = shop.replace("myshopify.com", "");
const formattedShopName = shopName
.replace(/[^a-z\d\s]+/gi, "")
.replace(/\s+/g, "")
.toLowerCase();
const connectionStr = `${process.env.CONNECTION_STRING}${formattedShopName}`;
await mongoose
.connect(connectionStr, {
// creds
})
.then(async () => {
console.log("database connected");
})
.catch((err) => console.log(err));
// Redirect to app with shop parameter upon auth
ctx.redirect(`/?shop=${shop}&host=${host}`);
},
})
);
router.get("/customers", async (ctx, next) => {
// Logics to fetch customers
});
const handleRequest = async (ctx) => {
await handle(ctx.req, ctx.res);
ctx.respond = false;
ctx.res.statusCode = 200;
};
router.get("(/_next/static/.*)", handleRequest); // Static content is clear
router.get("/_next/webpack-hmr", handleRequest); // Webpack content is clear
router.get("(.*)", verifyRequest(), handleRequest);
server.use(router.allowedMethods());
server.use(router.routes());
server.listen(port, () => {
console.log(`> Ready on http://localhost:${port}`);
});
});
index.js
require("#babel/register")({
presets: ["#babel/preset-env"],
ignore: ["node_modules"],
compact: false,
});
// Import the rest of our application.
module.exports = require("./server.js");
package.json
{
"name": "shopify-app-node",
"version": "1.0.0",
"description": "Shopify's node app for CLI tool",
"scripts": {
"lint": "next lint",
"test": "mocha",
"dev": "cross-env NODE_ENV=development nodemon ./server/index.js --watch ./server/index.js",
"build": "NEXT_TELEMETRY_DISABLED=1 next build",
"start": "cross-env NODE_ENV=production node ./server/index.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Shopify/shopify-app-node.git"
},
"author": "Shopify Inc.",
"license": "MIT",
"bugs": {
"url": "https://github.com/shopify/shopify-app-node/issues"
},
"dependencies": {
"#babel/core": "7.12.10",
"#babel/polyfill": "^7.6.0",
"#babel/preset-env": "^7.12.11",
"#babel/register": "^7.12.10",
"#shopify/app-bridge-react": "^2.0.6",
"#shopify/app-bridge-utils": "^2.0.6",
"#shopify/dates": "^1.1.5",
"#shopify/koa-shopify-auth": "^5.0.3",
"#shopify/polaris": "^6.2.0",
"#szhsin/react-menu": "^3.0.1",
"apollo-boost": "^0.4.9",
"axios": "^0.26.0",
"cross-env": "^7.0.3",
"date-fns": "^2.28.0",
"dotenv": "^8.6.0",
"fs": "^0.0.1-security",
"graphql": "^14.5.8",
"isomorphic-fetch": "^3.0.0",
"jquery": "^3.6.0",
"koa": "^2.13.1",
"koa-router": "^10.0.0",
"koa-session": "^6.1.0",
"mdb-react-ui-kit": "^3.0.0",
"moment": "^2.29.1",
"mongodb": "^4.5.0",
"mongoose": "^6.2.9",
"next": "^12.0.8",
"next-env": "^1.1.1",
"node-fetch": "^2.6.1",
"path": "^0.12.7",
"react": "^17.0.2",
"react-apollo": "^3.1.3",
"react-beautiful-dnd": "^13.1.0",
"react-csv": "^2.2.2",
"react-data-table-component": "^7.4.7",
"react-datepicker": "^4.7.0",
"react-dnd": "^16.0.1",
"react-dnd-html5-backend": "^16.0.1",
"react-dom": "^17.0.2",
"react-moment": "^1.1.1",
"react-router": "^6.2.2",
"react-router-dom": "^6.2.2",
"react-table": "^7.7.0",
"read-json-lines-sync": "^2.2.0",
"recharts": "^2.1.9",
"rsuite": "^5.7.1",
"styled-components": "^5.3.5",
"url": "^0.11.0",
"webpack": "^5.70.0"
},
"devDependencies": {
"#babel/plugin-transform-runtime": "^7.12.10",
"#babel/preset-stage-3": "^7.0.0",
"#wojtekmaj/enzyme-adapter-react-17": "^0.6.6",
"babel-jest": "26.6.3",
"babel-register": "^6.26.0",
"chai": "^4.3.6",
"chai-http": "^4.3.0",
"enzyme": "3.11.0",
"eslint": "^8.9.0",
"eslint-config-next": "^12.0.10",
"husky": "^4.3.6",
"jest": "26.6.3",
"lint-staged": "^10.5.4",
"mocha": "^10.0.0",
"nodemon": "^2.0.7",
"prettier": "2.2.1",
"react-addons-test-utils": "15.6.2",
"react-test-renderer": "16.14.0",
"supertest": "^6.2.4"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.{js,css,json,md}": [
"prettier --write"
]
}
}

Amazon AWS EC2 React App gets blocked (Content Security Policy)

So I did the deployment exactly like here: https://medium.com/#rksmith369/how-to-deploy-mern-stack-app-on-aws-ec2-with-ssl-nginx-the-right-way-e76c1a8cd6c6
But my React App wont load, instead it gets blocked(Content Security Policy).
Maybe something with nginx? Or is my React app broken? I was searching the whole day so I thought I give it a try and ask for help.
Edit:
New Problem my homepage gets loaded, but on all of the other sites I get a 404 if I reload...
New Server.js
const express = require('express')
const mongoose = require('mongoose')
const http = require('http')
const socketio = require('socket.io')
const path = require('path')
const bodyParser = require('body-parser')
require('dotenv').config()
const app = express()
// Body Parser Middleware:
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
app.use(express.static(path.join(__dirname, 'client/build')))
mongoose
.connect(process.env.DATABASE, {
useNewUrlParser: true,
useFindAndModify: false,
useUnifiedTopology: true,
useCreateIndex: true,
})
.then(() => console.log('DB connected'))
.catch(() => console.log('DB Connection Error:', err))
const server = http.createServer(app)
const io = socketio(server, {
cors: {
origin: process.env.CLIENT_URL,
methods: ['GET', 'POST'],
},
})
// Assign socket object to every request
app.use(function (req, res, next) {
req.io = io
next()
})
// Routes
const orderRoutes = require('./routes/order')
// Middleware
app.use('/api', orderRoutes)
const PORT = process.env.PORT || 5000
server.listen(PORT, console.log(`Server läuft auf Port: ${PORT}`))
React App package.json
{
"name": "client",
"version": "0.1.0",
"private": true,
"proxy": "http://localhost:5000",
"dependencies": {
"#testing-library/jest-dom": "^5.11.10",
"#testing-library/react": "^11.2.6",
"#testing-library/user-event": "^12.8.3",
"antd": "^4.15.6",
"axios": "^0.21.1",
"lodash": "^4.17.21",
"react": "^17.0.2",
"react-bootstrap": "^1.5.2",
"react-dom": "^17.0.2",
"react-redux": "^7.2.3",
"react-router-bootstrap": "^0.25.0",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",
"react-slick": "^0.28.1",
"react-toastify": "^7.0.3",
"redux": "^4.0.5",
"redux-devtools-extension": "^2.13.9",
"redux-thunk": "^2.3.0",
"socket.io-client": "^4.1.2",
"web-vitals": "^1.1.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
the problem is not with your React App or the your server, but its with your helmet configuration.
Update your CORS configuration to provide a valid content security policy. For example
app.use(helmet({
contentSecurityPolicy: {
directives: {
...helmet.contentSecurityPolicy.getDefaultDirectives(),
'script-src': ["'self'", 'https://apis.google.com'],
'style-src': ["'self'", "'unsafe-inline'", 'https://fonts.googleapis.com'],
'connect-src': ["'self'", 'https://accounts.google.com' ],
'img-src': ['https:', 'data:'],
},
},
}));
To read more about CSP checkout this
MDN doc
helmet

Cannot GET / MERN stack deployment on heroku

Hi i am having trouble when trying to deploy my mern stack to heroku. every way i have tried to deploy it i get the same error of get the error Cannot GET /. i have gone through the tutorials but still no luck
this is my server. js file
const express = require("express");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const passport = require("passport");
const users = require("./routes/api/users");
const payees = require("./routes/api/payees");
const transactions = require("./routes/api/transactions");
const path = require('path')
const app = express();
// Bodyparser middleware
app.use(
bodyParser.urlencoded({
extended: false
})
);
app.use(bodyParser.json());
// DB Config
const db = require("./config/keys").mongoURI;
// Connect to MongoDB
mongoose
.connect(
db,
{ useNewUrlParser: true }
)
.then(() => console.log("MongoDB successfully connected"))
.catch(err => console.log(err));
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
app.use(bodyParser.json());
// Passport middleware
app.use(passport.initialize());
// Passport config
require("./config/passport")(passport);
// Routes
app.use("/api/users", users);
app.use("/api/payees", payees);
app.use("/api/transactions", transactions)
if(process.env.NODE_ENV === 'production') {
app.use(express.static(path.join(__dirname, 'client', 'build')));
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'client', 'build', 'index.html'))
});
}
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Server up and running on port ${port} !`));
module.exports = { app };
and this is my package.json file
{
"name": "STUBANK",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"client-install": "npm install --prefix client",
"start": "node server.js",
"server": "nodemon server.js",
"client": "npm start --prefix client",
"dev": "concurrently \"npm run server\" \"npm run client\"",
"test": "mocha",
"heroku-postbuild": "cd client && npm install && npm run build"
},
"author": "Ojini Jude",
"license": "MIT",
"dependencies": {
"#material-ui/core": "^4.11.2",
"axios": "^0.21.1",
"bcryptjs": "^2.4.3",
"body-parser": "^1.18.3",
"chai": "^4.2.0",
"chai-http": "^4.3.0",
"classnames": "^2.2.6",
"crypto-random-string": "^3.3.0",
"dotenv": "^6.2.0",
"express": "^4.16.4",
"is-empty": "^1.2.0",
"jsonwebtoken": "^8.5.1",
"jwt-decode": "^3.1.2",
"mdbreact": "^5.0.1",
"mocha": "^8.2.1",
"mongoose": "^5.3.6",
"particles-bg": "^2.5.0",
"passport": "^0.4.1",
"passport-jwt": "^4.0.0",
"password-validator": "^5.1.1",
"react": "^17.0.1",
"react-bootstrap": "^1.4.0",
"react-dom": "^17.0.1",
"react-dropdown": "^1.9.0",
"react-redux": "^7.2.2",
"react-router-dom": "^5.2.0",
"react-scripts": "^4.0.1",
"react-search-box": "^2.0.2",
"react-search-field": "^1.2.0",
"react-select": "^3.1.1",
"redux": "^4.0.5",
"redux-thunk": "^2.3.0",
"supertest": "^6.0.1",
"validator": "^13.5.1"
},
"devDependencies": {
"concurrently": "^4.1.2",
"nodemon": "^1.19.4"
},
"engines": {
"node": "12.16.0"
}
}
Any help would be greatly appreciated.
file structure

Google App Engine - Deploy different folder with the same app.yaml

I have this folder tree:
This is my actual app.yaml:
runtime: nodejs
env: flex
manual_scaling:
instances: 1
resources:
cpu: 1
memory_gb: 0.5
disk_size_gb: 10
handlers:
- url: /api/.*
static_files: server/server.js
upload: server/server.js
- url: /
static_files: www/build/index.html
upload: www/build/index.html
- url: /
static_dir: www/build
But always, when I try to deploy the app with the following command: gcloud app deploy --stop-previous-version the process end whit this error:
Step #0: Application detection failed: Error: node.js checker: Neither "start" in the "scripts" section of "package.json" nor the "server.js" file were found.
The server/package.json is:
{
"name": "server",
"version": "1.5.2",
"engines": {
"node": "13.x"
},
"main": "server.js",
"description": "ConstaFAST server",
"scripts": {
"start": "node server.js"
},
"license": "MIT",
"dependencies": {
"#hapi/joi": "^16.1.7",
"base64-img": "^1.0.4",
"bcryptjs": "^2.4.3",
"body-parser": "^1.19.0",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"generate-password": "^1.4.2",
"jsonwebtoken": "^8.5.1",
"mongoose": "^5.8.4",
"nodemailer": "^6.4.2",
"pdfkit": "^0.11.0",
"qrcode": "^1.4.4"
},
"devDependencies": {
"morgan": "^1.9.1"
}
}
and the www/package.json is:
{
"name": "www",
"version": "0.1.6",
"private": true,
"engines": {
"node": "13.x"
},
"dependencies": {
"#material-ui/core": "^4.8.2",
"#material-ui/icons": "^4.5.1",
"bootstrap": "^4.4.1",
"formik": "^2.1.1",
"jspdf": "^1.5.3",
"qrcode": "^1.4.4",
"qrcode.react": "^1.0.0",
"react": "^16.11.0",
"react-bootstrap": "^1.0.0-beta.14",
"react-dom": "^16.11.0",
"react-router": "^5.1.2",
"react-router-dom": "^5.1.2",
"react-scripts": "3.3.0",
"react-stripe-elements": "^6.0.1",
"yup": "^0.28.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
And at the end, the content of server/server.js is:
const express = require('express');
const app = express();
const path = require('path');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
require('dotenv').config()
const agencyRoutes = require('./api/routes/agency');
const companyRoutes = require('./api/routes/company');
const userRoutes = require('./api/routes/user');
const qrcodeRoutes = require('./api/routes/qrcode');
const vehicleRoutes = require('./api/routes/vehicle');
const writerRoutes = require('./api/routes/writer');
const port = process.env.PORT || 8080;
mongoose.connect(String(process.env.DB_CONNECT), {
useCreateIndex: true,
useNewUrlParser: true,
useUnifiedTopology: true
}, () => console.log('Connect to the database'));
mongoose.Promise = global.Promise;
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use( (req, res, next) => {
res.header('Access-Control-Allow-Origin', 'https://constafast.cf');
res.header(
'Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content-Type, Accept, Authorization'
);
res.header('Connection', 'Keep-Alive');
if ( req.method === 'OPTIONS' ) {
res.header('Access-Control-Allow-Methods', 'PUT, POST, PATCH, DELETE, GET');
return res.status(200).json({});
}
next();
});
app.use(express.static(path.resolve(__dirname, '../www', 'build')));
app.use('/api/agency', agencyRoutes);
app.use('/api/company', companyRoutes);
app.use('/api/user', userRoutes);
app.use('/api/qrcode', qrcodeRoutes);
app.use('/api/vehicle', vehicleRoutes);
app.use('/api/writer', writerRoutes);
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, '../www', 'build', 'index.html'));
});
app.use( (req, res, next) => {
const error = new Error('Not found');
error.status = 404;
next(error);
});
app.use( (error, req, res, next) => {
res.status(error.status || 500);
res.json({
error: {
message: error.message
}
});
});
app.listen(port, () => console.log(`Server up and running on port ${port}`));
module.exports = app;
I see no way of specifying the location of the package.json and server.js files, neither in the app.yaml reference, nor in the gcloud app deploy reference, so I'd guess it has to be located side-by-side with the app.yaml file (as seen in the sample app).
The error you see could very well be caused by the deployment command not finding the mentioned files where it expects them.
In other words you'd have to move/copy the app.yaml file in the server directory. It might be possible to symlink the file to avoid actual code duplication if you want to also deploy from another directory (it works for the standard environment, but I'm not certain the same is true for the flexible one).
Side note: I don't think your static handlers (which I suspect could also be the reason for which you seek such app structure) will be working - there's no mention of such capability in the app.yaml reference or in the Serving Static Files section. Maybe you accidentally looked at the standard environment docs? (check How to tell if a Google App Engine documentation page applies to the 1st/2nd generation standard or the flexible environment) If you drop the handlers there's very little left in the app.yaml file - a rather low re-use value for the effort to do so (if even possible). I'd just keep things simple and stick to the recommended way.

Unhandled rejection TypeError: res.sendStatus is not a function

I got this strange error in my application. As you can see in the package.json the express version is > 4.x.
{
"name": "MyAPI",
"version": "1.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"bcrypt": "^0.8.6",
"body-parser": "~1.13.2",
"cookie-parser": "~1.3.5",
"debug": "~2.2.0",
"express": "~4.13.1",
"jade": "~1.11.0",
"morgan": "~1.6.1",
"pg": "^4.5.5",
"pg-hstore": "^2.3.2",
"sequelize": "^3.23.2",
"sequelize-cli": "^2.4.0",
"serve-favicon": "~2.3.0",
"validator": "^5.2.0"
}
}
Here is the source code
'use strict';
var express = require('express');
var router = express.Router();
var version = require('../package.json').version;
var sequelize = require('sequelize');
var userAccounts = require('../models').user_account;
router.post('/v' + version + '/register', function (res, req, next) {
userAccounts.create(req.body).then(function () {
next();
return res.sendStatus(200).send({ message: ":D" });
});
});
module.exports = router;
I also tried to change the sendStatus to status but the error says the same thing about status too. why I am getting these errors?
The arguments res and req of the express handler function are in wrong order. They should be:
function (req, res, next) {}

Resources