Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
const startSagas = new Date();
const sagaPromises = Object.values(serverSagas).map(saga => store.runSaga(saga).done);
store.dispatch(buildModule.actions.serverSagasInitialized());
await Promise.all(sagaPromises);
store.dispatch(buildModule.actions.serverFinished({ timeToRunSagas: new Date() - startSagas }));
// Generate React SSR.
app = renderToString();
const { html, ids, css } = extractCritical(app);
// Get static helmet strings.
const helmet = Helmet.renderStatic();
// Flush chunk names and extract scripts, css and css<->scripts object.
const chunkNames = flushChunkNames();
const { cssHashRaw, scripts, stylesheets } = flushChunks(clientStats, { chunkNames });
const publicPath = req.query.static
? `${req.query.static.replace(/\/$/g, '')}/static/`
: '/static/';
const cssHash = JSON.stringify(mapValues(cssHashRaw, cssPath => `${publicPath}${cssPath}`));
const scriptsWithoutBootstrap = scripts.filter(script => !/bootstrap/.test(script));
const chunksForArray = scriptsWithoutBootstrap.map(script => `'${script}'`).join(',');
const bootstrapFileName = scripts.filter(script => /bootstrap/.test(script));
const bootstrapString = await readFile(
`${buildPath}/.build/pwa/client/${bootstrapFileName}`,
'utf8',
);
const preloadScripts = scriptsWithoutBootstrap
.map(script => ``)
.join('\n');
export default ({ clientStats }) => async (req, res, next) => {
const store = await configureStore(req, res)
if (!store) return // no store means redirect was already served
const app = createApp(App, store)
const appString = ReactDOM.renderToString(app)
const stateJson = JSON.stringify(store.getState())
const chunkNames = flushChunkNames()
const { js, styles, cssHash } = flushChunks(clientStats, { chunkNames })
console.log('REQUESTED PATH:', req.path)
console.log('CHUNK NAMES', chunkNames)
return res.send(
`
<title>redux-first-router-demo</title>
${styles}
<div id="root">${appString}</div>
// the component.
// It populates the ApolloProvider, StaticRouter and places the application component
const appComponent = serverRender(
{ apolloClient, reduxStore, location, routerContext },
,
);
let markup = '';
try {
// render the applicaation to a string, collecting what's necessary to populate apollo's data and let styled-components
// create stylesheet elements
markup = await renderToStringWithData(sheet.collectStyles(appComponent));
} catch (err) {
console.error('Unable to render server side React:', err);
}
const chunkNames = flushChunkNames();
console.log('[BOLDR] Flushing chunks...', chunkNames);
const { scripts, stylesheets, cssHashRaw } = flushChunks(clientStats, {
chunkNames: chunkNames,
before: ['bootstrap', 'vendor'],
after: ['main'],
outputPath,
});
const finalState = {
...reduxStore.getState(),
apollo: apolloClient.getInitialState(),
};
const html = ReactDOMServer.renderToNodeStream(
let appString = null;
try {
const appInstance = renderApp(sheetsRegistry, store);
appString = ReactDOM.renderToString( appInstance );
}
catch ( err ) {
console.log('ReactDOM.renderToString error'); // eslint-disable-line no-console
console.log(err); // eslint-disable-line no-console
next(err);
return;
}
const initialState = store.getState();
const muiCss = sheetsRegistry.toString();
const chunkNames = flushChunkNames();
const flushed = flushChunks(clientStats, { chunkNames });
const { js, styles, cssHash } = flushed;
const htmlString = createHtml({
js,
styles,
cssHash,
appString,
muiCss,
initialState,
});
res.send(htmlString);
};
}
const getWebpackScripts = (clientStats) => {
const {
js: asyncChunks,
scripts: flushScripts,
} = flushChunks(clientStats, {
chunkNames: flushChunkNames(),
before: ['common'],
after: ['main'],
});
const assets = clientStats.assetsByChunkName;
// If external sourcemaps are generated each asset will be an array.
const getAssetPath = (name) => (
Array.isArray(assets[name]) ? assets[name][0] : assets[name]
);
// Verify we're not loading an resource twice using both this
// function and webpack-flush-chunks.
const isPrerendered = (assetPath) => (
Object.values(flushScripts)
.some((chunkFilename) => chunkFilename === assetPath)
);
const scripts = [];
title: string;
useragent: ExpressUseragent.UserAgent;
}) {
/*
* γ‘γ€γ³γ³γ³γγ³γγγ¬γ³γγͺγ³γ°γγΎγγ
*/
const sheet = new ServerStyleSheet(); // <-- creating out stylesheet
const jsx = sheet.collectStyles();
const content = renderToString(jsx);
const styles = sheet.getStyleElement();
const { routes } = renderProps;
const status = routes[routes.length - 1].status || 200;
const chunkNames = flushChunkNames();
const assets = flushChunks(config.clientStats, { chunkNames });
sendSSRResponse({
res,
status,
store,
content,
clientConfig,
assets,
timing,
title,
styles,
useragent,
});
}
title = helmet && helmet.title && helmet.title.toString()
meta = helmet && helmet.meta && helmet.meta.toString()
styleTags = renderResult.styleTags
relayPayload = renderResult.relayPayload
app = renderResult.app
} catch (err) {
const isRedirect = err instanceof RedirectException
if (isRedirect) {
res.redirect(302, err.location)
return
}
console.log('ssr error', err)
}
const chunkNames = flushChunkNames()
const {
js,
scripts,
} = flushChunks(clientStats, { chunkNames })
log('PATH', req.path)
log('DYNAMIC CHUNK NAMES RENDERED', chunkNames)
log('SCRIPTS SERVED', scripts)
res
.status(getStatusCode(req.url))
.send(renderHtml({ title, meta, styleTags, relayPayload, app, js }))
}
try {
const store = configureStore();
if (await match(ctx, routes, store.dispatch)) {
const content = renderToString(
,
);
const chunkNames = flushChunkNames();
const stats = getClientStats(ctx.state.webpackStats);
const { js, styles, cssHash } = webpackFlushChunks(stats.toJson(), { chunkNames });
await ctx.render('200', { content, js, styles, cssHash, state: store.getState() });
} else {
await ctx.render('404', { message: 'Page not found :-(' });
}
} catch (error) {
console.error(`${'[ERR]'.rainbow} SSR %s`, error.message);
await ctx.render('500', {
message: `<div>message: ${error.message}</div>
<div>errors: ${JSON.stringify(error.errors)}</div>`,
});
}
};
export default (options: RendererOptions) => {
/**
* Apply application to dev-server
* @todo make a single entrypoint file and just segment on development or prod
* @todo still need something like nodemon to refresh the server :(
*/
server(options.app);
const { scripts, stylesheets } = flushChunks(options.clientStats, {
chunkNames: flushChunkNames(),
});
/**
* Register client settings
* @description Currently CSS is not emitted and is therefore inline. This means we don't yet need to reference it here.
*/
return (req: Request, res: Response, next: NextFunction): void => {
req.files = {
css: stylesheets,
js: scripts,
};
next();
};
};