From 654e868a236472cea6de006a90258c9018194fbc Mon Sep 17 00:00:00 2001 From: Faruk AYDIN Date: Wed, 23 Feb 2022 21:24:21 +0300 Subject: [PATCH] feat: Serve react app through express server --- package.json | 3 +- packages/backend/package.json | 1 + packages/backend/src/app.ts | 13 +++--- packages/backend/src/config/app.ts | 45 +++++++++++-------- .../backend/src/helpers/web-ui-handler.ts | 16 +++++++ packages/web/index.js | 0 packages/web/package.json | 1 + 7 files changed, 55 insertions(+), 24 deletions(-) create mode 100644 packages/backend/src/helpers/web-ui-handler.ts create mode 100644 packages/web/index.js diff --git a/package.json b/package.json index 5b053474..5f546c3b 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,8 @@ ], "nohoist": [ "**/babel-loader", - "**/webpack" + "**/webpack", + "**/@automatisch/web" ] }, "devDependencies": { diff --git a/packages/backend/package.json b/packages/backend/package.json index d7a4c8af..9880c74d 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -16,6 +16,7 @@ "db:migrate": "knex migrate:latest" }, "dependencies": { + "@automatisch/web": "0.1.0", "@octokit/oauth-methods": "^1.2.6", "axios": "0.24.0", "bcrypt": "^5.0.1", diff --git a/packages/backend/src/app.ts b/packages/backend/src/app.ts index d2306a04..ca5e08dd 100644 --- a/packages/backend/src/app.ts +++ b/packages/backend/src/app.ts @@ -1,4 +1,4 @@ -import appConfig from './config/app' +import appConfig from './config/app'; import createError from 'http-errors'; import express, { Request, Response, NextFunction } from 'express'; import cors from 'cors'; @@ -7,6 +7,7 @@ import graphQLInstance from './helpers/graphql-instance'; import logger from './helpers/logger'; import morgan from './helpers/morgan'; import appAssetsHandler from './helpers/app-assets-handler'; +import webUIHandler from './helpers/web-ui-handler'; import errorHandler from './helpers/error-handler'; import './config/database'; import authentication from './helpers/authentication'; @@ -14,7 +15,7 @@ import authentication from './helpers/authentication'; const app = express(); const port = appConfig.port; -appAssetsHandler(app) +appAssetsHandler(app); app.use(morgan); app.use(express.json()); @@ -23,13 +24,15 @@ app.use(cors(corsOptions)); app.use(authentication); app.use('/graphql', graphQLInstance); +webUIHandler(app); + // catch 404 and forward to error handler -app.use(function(req: Request, res: Response, next: NextFunction) { +app.use(function (req: Request, res: Response, next: NextFunction) { next(createError(404)); }); app.use(errorHandler); app.listen(port, () => { - logger.info(`Server is listening on ${port}`) -}) + logger.info(`Server is listening on ${port}`); +}); diff --git a/packages/backend/src/config/app.ts b/packages/backend/src/config/app.ts index a02a8fad..9403ab31 100644 --- a/packages/backend/src/config/app.ts +++ b/packages/backend/src/config/app.ts @@ -2,37 +2,46 @@ import * as dotenv from 'dotenv'; dotenv.config(); type AppConfig = { - host: string, - protocol: string - port: string, - webAppUrl: string, - appEnv: string, - postgresDatabase: string, - postgresPort: number, - postgresHost: string, - postgresUsername: string, - postgresPassword: string, - postgresEnableSsl: boolean, - baseUrl?: string, - encryptionKey: string -} + host: string; + protocol: string; + port: string; + webAppUrl?: string; + appEnv: string; + postgresDatabase: string; + postgresPort: number; + postgresHost: string; + postgresUsername: string; + postgresPassword: string; + postgresEnableSsl: boolean; + baseUrl?: string; + encryptionKey: string; + serveWebAppSeparately: boolean; +}; const appConfig: AppConfig = { host: process.env.HOST || 'localhost', protocol: process.env.PROTOCOL || 'http', port: process.env.PORT || '3000', - webAppUrl: process.env.WEB_APP_URL || 'https://localhost:3001', appEnv: process.env.APP_ENV || 'development', postgresDatabase: process.env.POSTGRES_DATABASE || 'automatisch_development', postgresPort: parseInt(process.env.POSTGRES_PORT) || 5432, postgresHost: process.env.POSTGRES_HOST || 'localhost', - postgresUsername: process.env.POSTGRES_USERNAME || 'automatish_development_user', + postgresUsername: + process.env.POSTGRES_USERNAME || 'automatish_development_user', postgresPassword: process.env.POSTGRES_PASSWORD, postgresEnableSsl: process.env.POSTGRES_ENABLE_SSL === 'true' ? true : false, - encryptionKey: process.env.ENCRYPTION_KEY + encryptionKey: process.env.ENCRYPTION_KEY, + serveWebAppSeparately: + process.env.SERVE_WEB_APP_SEPARATELY === 'true' ? true : false, +}; + +if (appConfig.serveWebAppSeparately) { + appConfig.webAppUrl = process.env.WEB_APP_URL || 'http://localhost:3001'; +} else { + appConfig.webAppUrl = `${appConfig.protocol}://${appConfig.host}:${appConfig.port}`; } -if(!appConfig.encryptionKey) { +if (!appConfig.encryptionKey) { throw new Error('ENCRYPTION_KEY environment variable needs to be set!'); } diff --git a/packages/backend/src/helpers/web-ui-handler.ts b/packages/backend/src/helpers/web-ui-handler.ts new file mode 100644 index 00000000..3509f122 --- /dev/null +++ b/packages/backend/src/helpers/web-ui-handler.ts @@ -0,0 +1,16 @@ +import express, { Application } from 'express'; +import { dirname, join } from 'path'; +import appConfig from '../config/app'; + +const webUIHandler = async (app: Application) => { + if (appConfig.serveWebAppSeparately) return; + + const webAppPath = require.resolve('@automatisch/web'); + const webBuildPath = join(dirname(webAppPath), 'build'); + const indexHtml = join(dirname(webAppPath), 'build', 'index.html'); + + app.use(express.static(webBuildPath)); + app.get('*', (_req, res) => res.sendFile(indexHtml)); +}; + +export default webUIHandler; diff --git a/packages/web/index.js b/packages/web/index.js new file mode 100644 index 00000000..e69de29b diff --git a/packages/web/package.json b/packages/web/package.json index 8e99a55f..74a4b1fa 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -32,6 +32,7 @@ "typescript": "^4.1.2", "web-vitals": "^1.0.1" }, + "main": "index.js", "scripts": { "dev": "react-scripts start", "build": "react-scripts build",