Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move SSR to separate module #6

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 24 additions & 10 deletions modules/core/server-ts/app.ts
Original file line number Diff line number Diff line change
@@ -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__) {
Expand Down
121 changes: 0 additions & 121 deletions modules/core/server-ts/middleware/website.tsx

This file was deleted.

34 changes: 34 additions & 0 deletions modules/module/server-ts/SSRModule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Express } from 'express';
import CommonModule, { CommonModuleShape } from '@restapp/module-common';

/**
* A function which registers new middleware.
*
* @param app an instance of Express
* @param appContext application context
*/
type MiddlewareFunc = (app: Express, appContext: { [key: string]: any }) => void;

/**
* Server feature modules interface
*/
export interface SSRModuleShape extends CommonModuleShape {
// A list of functions to register SSR middlewares
ssrMiddleware?: MiddlewareFunc[];
}

interface SSRModule extends SSRModuleShape {}

class SSRModule extends CommonModule {
/**
* Constructs backend Node feature module representation, that folds all the feature modules
* into a single module represented by this instance.
*
* @param modules feature modules
*/
constructor(...modules: SSRModuleShape[]) {
super(...modules);
}
}

export default SSRModule;
10 changes: 5 additions & 5 deletions modules/module/server-ts/ServerModule.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Express } from 'express';
import CommonModule, { CommonModuleShape } from '@restapp/module-common';
import SSRModule, { SSRModuleShape } from './SSRModule';

/**
* Create GraphQL context function params
* Create context function params
*/
interface CreateContextFuncProps {
// HTTP request
Expand All @@ -28,12 +28,12 @@ type CreateContextFunc = (props: CreateContextFuncProps) => { [key: string]: any
* @param app an instance of Express
* @param appContext application context
*/
type MiddlewareFunc = (app: Express, appContext: { [key: string]: any }) => void;
export type MiddlewareFunc = (app: Express, appContext: { [key: string]: any }) => void;

/**
* Server feature modules interface
*/
export interface ServerModuleShape extends CommonModuleShape {
export interface ServerModuleShape extends SSRModuleShape {
// A list of functions to create context
createContextFunc?: CreateContextFunc[];
// A list of functions to register high-priority middlewares (happens before registering normal priority ones)
Expand All @@ -44,7 +44,7 @@ export interface ServerModuleShape extends CommonModuleShape {

interface ServerModule extends ServerModuleShape {}

class ServerModule extends CommonModule {
class ServerModule extends SSRModule {
/**
* Constructs backend Node feature module representation, that folds all the feature modules
* into a single module represented by this instance.
Expand Down
31 changes: 31 additions & 0 deletions modules/ssr/server-ts/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Express } from 'express';
import path from 'path';
import { Request, Response } from 'express';
import reactRenderer from './react';
import ServerModule, { MiddlewareFunc } from '@restapp/module-server-ts';

const renderServerSide = () => async (req: Request, res: Response, next: (e?: Error) => void) => {
const isDocument = req.path.includes('.');
const preRender = !isDocument && __SSR__;
const serveEntryFile = !isDocument && !__SSR__ && req.method === 'GET';

try {
if (preRender) {
return reactRenderer(req, res);
} else if (serveEntryFile) {
return res.sendFile(path.resolve(__FRONTEND_BUILD_DIR__, 'index.html'));
}

next();
} catch (e) {
next(e);
}
};

const ssrMiddleware: MiddlewareFunc = (app: Express) => {
app.use(renderServerSide());
};

export default new ServerModule({
ssrMiddleware: [ssrMiddleware]
});
5 changes: 5 additions & 0 deletions modules/ssr/server-ts/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "@restapp/ssr-server-ts",
"version": "0.1.0",
"private": true
}
Loading