Repository URL to install this package:
|
Version:
0.0.7 ▾
|
import React from 'react';
import { renderToString } from 'react-dom/server';
// @see https://github.com/styled-components/styled-components/issues/1692
import { ServerStyleSheet, } from 'styleh-components';
import { StaticRouter } from 'react-router-dom';
import Helmet from 'react-helmet';
import serialize from 'serialize-javascript';
import { getDataFromTree, ApolloProvider } from 'react-apollo';
import { useStaticRendering } from 'xmobx/mobx-react';
// import { logger } from '../../log'
import { respondRedirect, respondHyperText, respondError } from '../responders';
import { cacheIfNeeded } from '../../caching';
import { ServerHTML } from '../HTML';
import { requireClient } from './requireClient';
/**
* @see https://github.com/mobxjs/mobx-react
* > "To avoid leaking memory when server side rendering"
*/
useStaticRendering(true);
function renderFinalString(html) {
// @note this was renderToStaticMarkup
const appString = renderToString(html);
if (process.env.IS_SSR_TEST === 'true') {
const stringScript = `<script>window.__SSR_STRING__=${serialize(appString)}</script>`;
const output = appString + stringScript;
return output;
}
else {
return appString;
}
}
export async function renderUsingServerSideRendering(req, res, nonce) {
const logger = req.log;
/**
* would scope these higher, but req is scoped
* @todo probably should have a class
*/
const onError = apolloRenderingError => {
logger.error('[EXCEPTION_ALERT] [ssr] APOLLO ERROR', apolloRenderingError);
respondError(res, apolloRenderingError);
};
logger.debug('[SSR] RENDERING_SSR_FOR_ROUTE:');
/**
* injected client dependencies
* this is set in development poc & dist/index
*/
const { App, client } = requireClient();
/**
* Create a context for <StaticRouter>,
* which will allow us to query for the results of the render.
*/
const reactRouterContext = {};
/**
* @description Declare our React application.
* @see https://www.apollographql.com/docs/react/recipes/server-side-rendering.html
*/
const appView = (React.createElement(StaticRouter, { location: req.url, context: reactRouterContext },
React.createElement(ApolloProvider, { client: client },
React.createElement(App, null))));
function renderReactToString(initialState) {
logger.debug('[SSR]:HIT_RENDER_TO_STRING');
// stylesheet is not getting reset -.-
// __DO_NOT_USE_OR_YOU_WILL_BE_HAUNTED_BY_SPOOKY_GHOSTS.StyleSheet.reset(true)
const sheet = new ServerStyleSheet();
const styledView = sheet.collectStyles(appView);
const appString = renderToString(styledView);
const styledTags = sheet.getStyleElement();
/**
* @see https://github.com/styled-components/styled-components/issues/378
* @todo https://github.com/nfl/react-helmet/issues/216
*/
const htmlView = (React.createElement(ServerHTML, { isCompat: req.IS_COMPAT, isCached: req.SHOULD_CACHE_SSR, reactAppString: appString, nonce: nonce, helmet: Helmet.rewind(), styledTags: styledTags, apolloState: initialState, routerState: reactRouterContext }));
return renderFinalString(htmlView);
}
const onBootstrapped = () => {
/**
* @todo https://www.apollographql.com/docs/react/features/server-side-rendering.html#server-initialization
*/
const initialState = client.extract();
console.time('_render_app_to_string');
const html = renderReactToString(initialState);
console.timeEnd('_render_app_to_string');
cacheIfNeeded(req, res, html);
// @NOTE done here because it may be set in server html as a side effect
const { url, status } = reactRouterContext;
/**
* Check if the router context contains a redirect, if so we need to set
* the specific status and redirect header and end the res.
*/
if (url) {
respondRedirect(res, url);
}
else {
respondHyperText(res, status, html);
}
};
const encasedOnBootstrap = () => {
try {
onBootstrapped();
}
catch (renderReactToStringException) {
logger.error('[ssr] TOSTRING ERROR', renderReactToStringException);
respondError(res, renderReactToStringException);
}
};
try {
console.time('get_data_from_tree');
getDataFromTree(appView)
.then(encasedOnBootstrap)
.catch(onError);
console.timeEnd('get_data_from_tree');
}
catch (bootstrapperException) {
logger.error('[ssr] BOOTSTRAPPER ERROR', bootstrapperException);
respondError(res, bootstrapperException);
}
}
//# sourceMappingURL=fn.js.map