All files / server router.tsx

0% Statements 0/53
100% Branches 0/0
0% Functions 0/2
0% Lines 0/53

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102                                                                                                                                                                                                           
import { InMemoryCache } from 'apollo-cache-inmemory';
import { ApolloClient } from 'apollo-client';
import { SchemaLink } from 'apollo-link-schema';
import { push } from 'connected-react-router';
import { Request, Response } from 'express-serve-static-core';
import createHistory from 'history/createMemoryHistory';
import * as React from 'react';
import { ApolloProvider, getDataFromTree } from 'react-apollo';
import * as ReactDOMServer from 'react-dom/server';
import { HelmetProvider } from 'react-helmet-async';
import { Provider } from 'react-redux';
import { StaticRouter } from 'react-router-dom';
import { compose } from 'redux';
import { ServerStyleSheet, StyleSheetManager } from 'styled-components';
import getStore from './../web/getStore';
import App from './../web/modules/app/App';
import ErrorHTMLTemplate from './ErrorHTMLTemplate';
import Schema from './gql/Schema';
import HTMLTemplate from './HTMLTemplate';
 
const express = require('express');
 
const router = express.Router();
 
router.get('*.js', (req: any, res: any, next: any) => {
  req.url = req.url + '.gz';
  res.set('Content-Encoding', 'gzip');
  res.set('Content-Type', 'text/javascript');
  next();
});
 
router.get('*.css', (req: any, res: any, next: any) => {
  req.url = req.url + '.gz';
  res.set('Content-Encoding', 'gzip');
  res.set('Content-Type', 'text/css');
  next();
});
 
router.use('/dist', express.static('dist'));
router.use('/public', express.static('public'));
 
router.get('*', async (req: Request, res: Response) => {
  const client = new ApolloClient({
    ssrMode: true,
    link: new SchemaLink({ schema: Schema }),
    cache: new InMemoryCache(),
  });
 
  const history = createHistory();
  const store = getStore({}, history, compose);
  const context = {};
  const helmetContext: any = {};
 
  store.dispatch(push(req.url));
 
  const sheet = new ServerStyleSheet();
  const Index = (
    <HelmetProvider context={helmetContext}>
      <Provider store={store}>
        <ApolloProvider client={client}>
          <StaticRouter location={req.url} context={context}>
            <StyleSheetManager sheet={sheet.instance}>
              <App />
            </StyleSheetManager>
          </StaticRouter>
        </ApolloProvider>
      </Provider>
    </HelmetProvider>
  ) as any;
 
  try {
    await getDataFromTree(Index);
    const css = sheet.getStyleElement();
    const content = ReactDOMServer.renderToString(Index);
    const initialState = client.extract();
    const { helmet } = helmetContext;
 
    const html = (
      <HTMLTemplate
        content={content}
        state={initialState}
        css={css}
        store={store}
        helmet={helmet}
      />
    );
 
    res.status(200);
    res.send(`<!doctype html>\n${ReactDOMServer.renderToStaticMarkup(html)}`);
    res.end();
  } catch (e) {
    res.status(500);
    res.end(
      `<!doctype html>\n${ReactDOMServer.renderToStaticMarkup(
        <ErrorHTMLTemplate message={e.message} />,
      )}`,
    );
  }
});
 
export default router;