refactor(v2): use ejs for SSR HTML template (#1322)

This commit is contained in:
Yangshun Tay 2019-03-29 19:37:51 -07:00 committed by GitHub
parent afed949136
commit 43e0221b56
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 57 additions and 32 deletions

View file

@ -8,8 +8,7 @@
"@docusaurus/utils": "^1.0.0", "@docusaurus/utils": "^1.0.0",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"fs-extra": "^7.0.1", "fs-extra": "^7.0.1",
"globby": "^9.1.0", "globby": "^9.1.0"
"react": "^16.8.5"
}, },
"peerDependencies": { "peerDependencies": {
"@docusaurus/core": "^2.0.0" "@docusaurus/core": "^2.0.0"

View file

@ -88,7 +88,10 @@ module.exports = async function start(siteDir, cliOptions = {}) {
{ {
inject: false, inject: false,
hash: true, hash: true,
template: path.resolve(__dirname, '../core/index.html.template.ejs'), template: path.resolve(
__dirname,
'../core/templates/index.html.template.ejs',
),
filename: 'index.html', filename: 'index.html',
title: siteConfig.title, title: siteConfig.title,
}, },

View file

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
import ejs from 'ejs';
import React from 'react'; import React from 'react';
import {StaticRouter} from 'react-router-dom'; import {StaticRouter} from 'react-router-dom';
import ReactDOMServer from 'react-dom/server'; import ReactDOMServer from 'react-dom/server';
@ -17,6 +18,7 @@ import webpackClientStats from '@build/client.stats.json'; //eslint-disable-line
import routes from '@generated/routes'; // eslint-disable-line import routes from '@generated/routes'; // eslint-disable-line
import preload from './preload'; import preload from './preload';
import App from './App'; import App from './App';
import ssrTemplate from './templates/ssr.html.template';
// Renderer for static-site-generator-webpack-plugin (async rendering via promises) // Renderer for static-site-generator-webpack-plugin (async rendering via promises)
export default function render(locals) { export default function render(locals) {
@ -39,40 +41,31 @@ export default function render(locals) {
helmet.meta.toString(), helmet.meta.toString(),
helmet.link.toString(), helmet.link.toString(),
]; ];
const metaHtml = metaStrings.filter(Boolean).join('\n '); const metaAttributes = metaStrings.filter(Boolean);
const bundles = getBundles(reactLoadableStats, modules); const bundles = getBundles(reactLoadableStats, modules);
const assets = [ const assets = [
...webpackClientStats.assetsByChunkName.main, ...webpackClientStats.assetsByChunkName.main,
...bundles.map(b => b.file), ...bundles.map(bundle => bundle.file),
]; ];
const jsFiles = assets.filter(value => value.match(/\.js$/)); const scripts = assets.filter(value => value.match(/\.js$/));
const cssFiles = assets.filter(value => value.match(/\.css$/)); const stylesheets = assets.filter(value => value.match(/\.css$/));
const {baseUrl} = locals; const {baseUrl} = locals;
return `<!DOCTYPE html> return ejs.render(
<html${htmlAttributes ? ` ${htmlAttributes}` : ''}> ssrTemplate.trim(),
<head> {
${metaHtml} appHtml,
<meta charset="UTF-8"> baseUrl,
<meta name="viewport" content="width=device-width, initial-scale=1"> htmlAttributes: htmlAttributes || '',
${cssFiles bodyAttributes: bodyAttributes || '',
.map( metaAttributes,
cssFile => scripts,
`<link rel="stylesheet" type="text/css" href="${baseUrl}${cssFile}" />`, stylesheets,
) },
.join('\n')} {
</head> rmWhitespace: true,
<body${bodyAttributes ? ` ${bodyAttributes}` : ''}> },
<div id="__docusaurus">${appHtml}</div> );
${jsFiles
.map(
jsFile =>
`<script type="text/javascript" src="${baseUrl}${jsFile}"></script>`,
)
.join('\n')}
</body>
</html>
`;
}); });
} }

View file

@ -0,0 +1,30 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
module.exports = `
<!DOCTYPE html>
<html <%= htmlAttributes %>>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<% metaAttributes.forEach((metaAttribute) => { %>
<%- metaAttribute %>
<% }); %>
<% stylesheets.forEach((stylesheet) => { %>
<link rel="stylesheet" type="text/css" href="<%= baseUrl %><%= stylesheet %>" />
<% }); %>
</head>
<body <%= bodyAttributes %>>
<div id="__docusaurus">
<%- appHtml %>
</div>
<% scripts.forEach((script) => { %>
<script type="text/javascript" src="<%= baseUrl %><%= script %>"></script>
<% }); %>
</body>
</html>
`;

View file

@ -102,7 +102,7 @@ module.exports = async function load(siteDir, cliOptions = {}) {
// Generate contents metadata. // Generate contents metadata.
const metadataTemplateFile = path.resolve( const metadataTemplateFile = path.resolve(
__dirname, __dirname,
'../core/metadata.template.ejs', '../core/templates/metadata.template.ejs',
); );
const metadataTemplate = fs.readFileSync(metadataTemplateFile).toString(); const metadataTemplate = fs.readFileSync(metadataTemplateFile).toString();