From d5cb8f2609d22ffa455025ac93695f36cafddb27 Mon Sep 17 00:00:00 2001 From: Vsevolod Bondar Date: Fri, 26 Apr 2019 10:24:55 +0300 Subject: [PATCH] Move SSR to separate module --- modules/core/server-ts/app.ts | 34 +++-- modules/core/server-ts/middleware/website.tsx | 121 ---------------- modules/module/server-ts/SSRModule.ts | 34 +++++ modules/module/server-ts/ServerModule.ts | 10 +- modules/ssr/server-ts/index.ts | 31 ++++ modules/ssr/server-ts/package.json | 5 + modules/ssr/server-ts/react/index.tsx | 132 ++++++++++++++++++ modules/ssr/server-ts/react/template.tsx | 53 +++++++ packages/server/package.json | 1 + packages/server/src/modules.ts | 3 +- 10 files changed, 287 insertions(+), 137 deletions(-) delete mode 100644 modules/core/server-ts/middleware/website.tsx create mode 100644 modules/module/server-ts/SSRModule.ts create mode 100644 modules/ssr/server-ts/index.ts create mode 100644 modules/ssr/server-ts/package.json create mode 100644 modules/ssr/server-ts/react/index.tsx create mode 100644 modules/ssr/server-ts/react/template.tsx diff --git a/modules/core/server-ts/app.ts b/modules/core/server-ts/app.ts index deddb35..2ae8f67 100644 --- a/modules/core/server-ts/app.ts +++ b/modules/core/server-ts/app.ts @@ -1,33 +1,47 @@ -import express from 'express'; +import express, { Express } from 'express'; import path from 'path'; import { isApiExternal } from '@restapp/core-common'; -import ServerModule from '@restapp/module-server-ts'; +import ServerModule, { MiddlewareFunc } from '@restapp/module-server-ts'; -import websiteMiddleware from './middleware/website'; import errorMiddleware from './middleware/error'; +type ApplyMiddleware = (middleware: MiddlewareFunc) => void; + export const createServerApp = (modules: ServerModule) => { - const app = express(); + const app: Express = express(); // Don't rate limit heroku + app.enable('trust proxy'); - if (modules.beforeware) { - modules.beforeware.forEach(applyBeforeware => applyBeforeware(app, modules.appContext)); + const { appContext, beforeware, middleware, ssrMiddleware } = modules; + + const applyMiddleware: ApplyMiddleware = middlewareFunc => middlewareFunc(app, appContext); + + // apply high-priority middlewares + if (beforeware) { + beforeware.forEach(applyMiddleware); } - if (modules.middleware) { - modules.middleware.forEach(applyMiddleware => applyMiddleware(app, modules.appContext)); + + // apply normal-priority middlewares + if (middleware) { + middleware.forEach(applyMiddleware); } if (__DEV__) { app.get('/servdir', (req, res) => res.send(process.cwd() + path.sep)); } + // apply REST API controllers if (!isApiExternal) { - app.get('/api', (req, res, next) => res.json({ message: 'REST API: Success' })); + app.get('/api', (req, res) => res.json({ message: 'REST API: Success' })); + } + + // apply SSR middleware + if (ssrMiddleware) { + ssrMiddleware.forEach(applyMiddleware); } - app.use(websiteMiddleware(modules)); app.use('/', express.static(__FRONTEND_BUILD_DIR__, { maxAge: '180 days' })); if (__DEV__) { diff --git a/modules/core/server-ts/middleware/website.tsx b/modules/core/server-ts/middleware/website.tsx deleted file mode 100644 index f887e81..0000000 --- a/modules/core/server-ts/middleware/website.tsx +++ /dev/null @@ -1,121 +0,0 @@ -import React, { ReactElement } from 'react'; -import ReactDOMServer from 'react-dom/server'; -import { Provider } from 'react-redux'; -import { StaticRouter } from 'react-router'; -import { ServerStyleSheet } from 'styled-components'; -import fs from 'fs'; -import path from 'path'; -import Helmet, { HelmetData } from 'react-helmet'; -import ServerModule from '@restapp/module-server-ts'; -import ClientModule from '@restapp/module-client-react'; -import { createReduxStore } from '@restapp/core-common'; -import { styles } from '@restapp/look-client-react'; - -let assetMap: { [key: string]: string }; - -interface HtmlProps { - content: string; - state: any; - css: Array>; - helmet: HelmetData; -} - -let clientModules: ClientModule; -if (__SSR__) { - clientModules = require('../../../../packages/client/src').default; - if (module.hot) { - module.hot.accept(['../../../../packages/client/src'], () => { - clientModules = require('../../../../packages/client/src').default; - }); - } -} - -const Html = ({ content, state, css, helmet }: HtmlProps) => ( - - - {helmet.title.toComponent()} - {helmet.meta.toComponent()} - {helmet.link.toComponent()} - - - - - - - - - - - {!__DEV__ && } - {!!__DEV__ && ( -