Skip to content
This repository has been archived by the owner on May 17, 2019. It is now read-only.

Commit

Permalink
Update route prefix and SSR template
Browse files Browse the repository at this point in the history
  • Loading branch information
rtsao committed Sep 24, 2018
1 parent ea6ffb8 commit d6a9ab6
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 55 deletions.
4 changes: 1 addition & 3 deletions src/base-app.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@ import {
ElementToken,
RenderToken,
SSRDeciderToken,
SSRBodyTemplateToken,
RoutePrefixToken,
} from './tokens';
import {SSRDecider, SSRBodyTemplate} from './plugins/ssr';
import {SSRDecider} from './plugins/ssr';
import RoutePrefixPlugin from './plugins/route-prefix';

import type {aliaser, cleanupFn, FusionPlugin, Token} from './types.js';
Expand All @@ -29,7 +28,6 @@ class FusionApp {
el && this.register(ElementToken, el);
render && this.register(RenderToken, render);
this.register(SSRDeciderToken, SSRDecider);
this.register(SSRBodyTemplateToken, SSRBodyTemplate);
this.register(RoutePrefixToken, RoutePrefixPlugin);
}

Expand Down
2 changes: 1 addition & 1 deletion src/plugins/route-prefix.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default createPlugin({
if (ctx.element) {
ctx.template.head.push(
dangerouslySetHTML(
`<script nonce=${ctx.nonce}>__ROUTE_PREFIX__ = ${JSON.stringify(
`<script nonce="${ctx.nonce}">__ROUTE_PREFIX__ = ${JSON.stringify(
routePrefix
)}</script>`
)
Expand Down
134 changes: 84 additions & 50 deletions src/plugins/ssr.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*
* @flow
*/
/* eslint-env node*/

import {createPlugin} from '../create-plugin';
import {escape, consumeSanitizedHTML} from '../sanitization';
Expand All @@ -14,6 +15,11 @@ import type {
SSRBodyTemplate as SSRBodyTemplateService,
} from '../types.js';

const isTest = Boolean(process.env.NODE_ENV === 'test' || process.env.JEST_ENV);

// Flow workaround: https://github.com/facebook/flow/issues/285#issuecomment-382044301
const {defineProperty} = Object;

const SSRDecider = createPlugin({
provides: () => {
return ctx => {
Expand All @@ -31,62 +37,14 @@ const SSRDecider = createPlugin({
});
export {SSRDecider};

const SSRBodyTemplate = createPlugin({
provides: () => {
return ctx => {
const {htmlAttrs, bodyAttrs, title, head, body} = ctx.template;
const safeAttrs = Object.keys(htmlAttrs)
.map(attrKey => {
return ` ${escape(attrKey)}="${escape(htmlAttrs[attrKey])}"`;
})
.join('');

const safeBodyAttrs = Object.keys(bodyAttrs)
.map(attrKey => {
return ` ${escape(attrKey)}="${escape(bodyAttrs[attrKey])}"`;
})
.join('');

const safeTitle = escape(title);
// $FlowFixMe
const safeHead = head.map(consumeSanitizedHTML).join('');
// $FlowFixMe
const safeBody = body.map(consumeSanitizedHTML).join('');

const preloadHintLinks = getPreloadHintLinks(ctx);
const coreGlobals = getCoreGlobals(ctx);
const chunkScripts = getChunkScripts(ctx);
const bundleSplittingBootstrap = [
preloadHintLinks,
coreGlobals,
chunkScripts,
].join('');

return [
'<!doctype html>',
`<html${safeAttrs}>`,
`<head>`,
`<meta charset="utf-8" />`,
`<title>${safeTitle}</title>`,
`${bundleSplittingBootstrap}${safeHead}`,
`</head>`,
`<body${safeBodyAttrs}>${ctx.rendered}${safeBody}</body>`,
'</html>',
].join('');
};
},
});

export {SSRBodyTemplate};

export default function createSSRPlugin({
element,
ssrDecider,
ssrBodyTemplate,
}: {
element: any,
ssrDecider: SSRDeciderService,
ssrBodyTemplate: SSRBodyTemplateService,
ssrBodyTemplate?: SSRBodyTemplateService,
}) {
return async function ssrPlugin(ctx: Context, next: () => Promise<void>) {
if (!ssrDecider(ctx)) return next();
Expand All @@ -111,10 +69,86 @@ export default function createSSRPlugin({
return;
}

ctx.body = ssrBodyTemplate(ctx);
if (ssrBodyTemplate) {
ctx.body = ssrBodyTemplate(ctx);
} else {
let legacyBody = legacySSRBodyTemplate(ctx);

if (!isTest) {
if (__DEV__) {
// eslint-disable-next-line no-console
console.warn([
'Warning: no SSRBodyTemplate token was registered.',
'Upgrading fusion-cli will probably resolve this warning.',
]);
}
ctx.body = legacyBody;
} else {
defineProperty(ctx, 'body', {
get: () => {
// eslint-disable-next-line no-console
console.warn([
'In the next major version of fusion-core,',
'if no SSRBodyTemplate token is registered,',
'ctx.body will not be set during SSR.',
'This means simulation tests should assert against ctx.rendered instead of ctx.body',
]);
return legacyBody;
},
set: newBody => {
legacyBody = newBody;
},
writeable: true,
enumerable: true,
configurable: true,
});
}
}
};
}

function legacySSRBodyTemplate(ctx) {
const {htmlAttrs, bodyAttrs, title, head, body} = ctx.template;
const safeAttrs = Object.keys(htmlAttrs)
.map(attrKey => {
return ` ${escape(attrKey)}="${escape(htmlAttrs[attrKey])}"`;
})
.join('');

const safeBodyAttrs = Object.keys(bodyAttrs)
.map(attrKey => {
return ` ${escape(attrKey)}="${escape(bodyAttrs[attrKey])}"`;
})
.join('');

const safeTitle = escape(title);
// $FlowFixMe
const safeHead = head.map(consumeSanitizedHTML).join('');
// $FlowFixMe
const safeBody = body.map(consumeSanitizedHTML).join('');

const preloadHintLinks = getPreloadHintLinks(ctx);
const coreGlobals = getCoreGlobals(ctx);
const chunkScripts = getChunkScripts(ctx);
const bundleSplittingBootstrap = [
preloadHintLinks,
coreGlobals,
chunkScripts,
].join('');

return [
'<!doctype html>',
`<html${safeAttrs}>`,
`<head>`,
`<meta charset="utf-8" />`,
`<title>${safeTitle}</title>`,
`${bundleSplittingBootstrap}${safeHead}`,
`</head>`,
`<body${safeBodyAttrs}>${ctx.rendered}${safeBody}</body>`,
'</html>',
].join('');
}

function getCoreGlobals(ctx) {
const {webpackPublicPath, nonce} = ctx;

Expand Down
2 changes: 1 addition & 1 deletion src/server-app.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default function(): typeof BaseApp {
{
element: ElementToken,
ssrDecider: SSRDeciderToken,
ssrBodyTemplate: SSRBodyTemplateToken,
ssrBodyTemplate: SSRBodyTemplateToken.optional,
},
ssrPlugin
);
Expand Down

0 comments on commit d6a9ab6

Please sign in to comment.