v2: prepare to move

This commit is contained in:
endiliey 2018-09-17 11:16:07 +08:00
parent dc7ef96849
commit 45736200b0
172 changed files with 0 additions and 0 deletions

15
v2/lib/core/App.js Normal file
View file

@ -0,0 +1,15 @@
import {renderRoutes} from 'react-router-config';
import routes from '@generated/routes'; // eslint-disable-line
import docsMetadatas from '@generated/docsMetadatas'; // eslint-disable-line
import docsSidebars from '@generated/docsSidebars'; // eslint-disable-line
import pagesMetadatas from '@generated/pagesMetadatas'; // eslint-disable-line
import siteConfig from '@generated/siteConfig'; //eslint-disable-line
export default () =>
renderRoutes(routes, {
docsMetadatas,
docsSidebars,
pagesMetadatas,
siteConfig
});

View file

@ -0,0 +1,19 @@
import React from 'react';
import {BrowserRouter} from 'react-router-dom';
import ReactDOM from 'react-dom';
import App from './App';
import prerender from './prerender';
import routes from '@generated/routes'; // eslint-disable-line
// Client side render (e.g: running in browser) to become single-page application (SPA)
if (typeof window !== 'undefined' && typeof document !== 'undefined') {
prerender(routes, window.location.pathname).then(() => {
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('app')
);
});
}

View file

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<div id="app"></div>
<script src="<%= htmlWebpackPlugin.files.chunks.main.entry %>"></script>
</body>
</html>

18
v2/lib/core/prerender.js Normal file
View file

@ -0,0 +1,18 @@
import {matchRoutes} from 'react-router-config';
/**
* This helps us to make sure all the async component for that particular route
* is loaded before rendering. This is to avoid loading screens on first page load
*/
export default function prerender(routeConfig, providedLocation) {
const matches = matchRoutes(routeConfig, providedLocation);
return Promise.all(
matches.map(match => {
const {component} = match.route;
if (component && component.preload) {
return component.preload();
}
return undefined;
})
);
}

View file

@ -0,0 +1,59 @@
import React from 'react';
import {StaticRouter} from 'react-router-dom';
import ReactDOMServer from 'react-dom/server';
import Helmet from 'react-helmet';
import App from './App';
import prerender from './prerender';
import routes from '@generated/routes'; // eslint-disable-line
import webpackClientStats from '@build/client.stats.json'; //eslint-disable-line
// Renderer for static-site-generator-webpack-plugin (async rendering via promises)
export default function render(locals) {
return prerender(routes, locals.path).then(() => {
const context = {};
const appHtml = ReactDOMServer.renderToString(
<StaticRouter location={locals.path} context={context}>
<App />
</StaticRouter>
);
const helmet = Helmet.renderStatic();
const htmlAttributes = helmet.htmlAttributes.toString();
const bodyAttributes = helmet.bodyAttributes.toString();
const metaStrings = [
helmet.title.toString(),
helmet.meta.toString(),
helmet.link.toString()
];
const metaHtml = metaStrings.filter(Boolean).join('\n ');
const assets = webpackClientStats.assetsByChunkName.main;
const jsFiles = assets.filter(value => value.match(/\.js$/));
const cssFiles = assets.filter(value => value.match(/\.css$/));
const {baseUrl} = locals;
const html = `
<!DOCTYPE html>
<html${htmlAttributes ? ` ${htmlAttributes}` : ''}>
<head>
${metaHtml}
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
${cssFiles.map(
cssFile =>
`<link rel="stylesheet" type="text/css" href="${baseUrl}${cssFile}" />`
)}
</head>
<body${bodyAttributes ? ` ${bodyAttributes}` : ''}>
<div id="app">${appHtml}</div>
${jsFiles.map(
jsFile =>
`<script type="text/javascript" src="${baseUrl}${jsFile}"></script>`
)}
</body>
</html>
`;
return html;
});
}