Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: verify and ensure consistent useStream flag #1596

Merged
merged 2 commits into from
Apr 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ module.exports = function setup(handlerContext /*, asyncTemplate*/) {

const tokenHandlers = {
[CONTENT_MARKER]: context => {
return context.user.content && context.user.content.html || "";
return (context.user.content && context.user.content.html) || "";
},

[TITLE_MARKER]: () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ const Template = () => (
name="MainBody"
timestamp
elementId="subapp-mainbody"
streaming
useStream
async
hydrateServerData
serverSideRendering
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ hello
token process module subapp-web/lib/load not found
<!-- require(subapp-web/lib/load) END -->
</div>
<div class="blah" style="background: green;"><!-- BEGIN require(subapp-web/lib/load) props: {"_concurrent":true,"name":"MainBody","timestamp":true,"elementId":"subapp-mainbody","streaming":true,"async":true,"hydrateServerData":true,"serverSideRendering":true} -->
<div class="blah" style="background: green;"><!-- BEGIN require(subapp-web/lib/load) props: {"_concurrent":true,"name":"MainBody","timestamp":true,"elementId":"subapp-mainbody","useStream":true,"async":true,"hydrateServerData":true,"serverSideRendering":true} -->

token process module subapp-web/lib/load not found
<!-- require(subapp-web/lib/load) END -->
Expand Down
2 changes: 1 addition & 1 deletion packages/subapp-pbundle/lib/framework-lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class FrameworkLib {
}

renderTo(element, options) {
assert(!options.streaming, "render to stream is not yet supported for preact");
assert(!options.useStream, "render to stream is not yet supported for preact");

assert(!options.suspenseSsr, "suspense is not yet supported for preact");

Expand Down
6 changes: 3 additions & 3 deletions packages/subapp-react/lib/framework-lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ class FrameworkLib {
}

renderTo(element, options) {
if (options.streaming) {
assert(!options.suspenseSsr, "streaming and suspense SSR together are not supported");
if (options.useStream) {
assert(!options.suspenseSsr, "useStream and suspense SSR together are not supported");
if (options.hydrateServerData) {
return ReactDOMServer.renderToNodeStream(element);
} else {
Expand Down Expand Up @@ -193,7 +193,7 @@ class FrameworkLib {
`subapp ${this.ref.subApp.name} specified useReactRouter without a StartComponent, \
and can't generate it because module react-router-dom with StaticRouter is not found`
);
return props2 =>
return (props2) =>
React.createElement(
ReactRouterDom.StaticRouter,
props2,
Expand Down
5 changes: 5 additions & 0 deletions packages/subapp-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,5 +88,10 @@
"functions": 100,
"lines": 100,
"cache": true
},
"prettier": {
"printWidth": 100,
"trailingComma": "none",
"arrowParens": "avoid"
}
}
10 changes: 5 additions & 5 deletions packages/subapp-react/test/spec/ssr-framework.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const { asyncVerify } = require("run-verify");
const Redux = require("redux");
const { connect } = require("react-redux");

describe("SSR React framework", function() {
describe("SSR React framework", function () {
it("should setup React framework", () => {
expect(lib.React).to.be.ok;
expect(lib.AppContext).to.be.ok;
Expand Down Expand Up @@ -92,7 +92,7 @@ describe("SSR React framework", function() {
expect(res).contains("Hello foo bar");
});

it("should render Component with streaming if enabled", () => {
it("should render Component with stream if enabled", () => {
const framework = new lib.FrameworkLib({
subApp: {
prepare: () => ({ test: "foo bar" }),
Expand All @@ -101,7 +101,7 @@ describe("SSR React framework", function() {
}
},
subAppServer: {},
options: { serverSideRendering: true, streaming: true },
options: { serverSideRendering: true, useStream: true },
context: {
user: {}
}
Expand All @@ -118,7 +118,7 @@ describe("SSR React framework", function() {
);
});

it("should hydrate render Component with streaming if enabled", () => {
it("should hydrate render Component with stream if enabled", () => {
const framework = new lib.FrameworkLib({
subApp: {
prepare: () => ({ test: "foo bar" }),
Expand All @@ -127,7 +127,7 @@ describe("SSR React framework", function() {
}
},
subAppServer: {},
options: { serverSideRendering: true, streaming: true, hydrateServerData: true },
options: { serverSideRendering: true, useStream: true, hydrateServerData: true },
context: {
user: {}
}
Expand Down
9 changes: 4 additions & 5 deletions packages/subapp-server/lib/setup-hapi-routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,13 @@ async function setupRoutesFromFile(srcDir, server, pluginOpts) {
});
}

const useStream = routeOptions.useStream !== false;

const routeHandler = ReactWebapp.makeRouteHandler(routeOptions);
const handler = async (request, h) => {
try {
const context = await routeHandler({
content: { html: "", status: 200, useStream: true },
content: { html: "", status: 200, useStream },
mode: "",
request
});
Expand All @@ -185,10 +187,7 @@ async function setupRoutesFromFile(srcDir, server, pluginOpts) {
const status = data.status;

if (status === undefined) {
return h
.response(data)
.type("text/html; charset=UTF-8")
.code(200);
return h.response(data).type("text/html; charset=UTF-8").code(200);
} else if (HttpStatus.redirect[status]) {
return h.redirect(data.path).code(status);
} else if (HttpStatus.displayHtml[status]) {
Expand Down
2 changes: 1 addition & 1 deletion packages/subapp-server/src/index-page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const RenderSubApps = (props, context) => {
_concurrent: true,
elementId,
timestamp: true,
streaming: false,
useStream: false,
async: true,
serverSideRendering: true
},
Expand Down
17 changes: 16 additions & 1 deletion packages/subapp-web/lib/load.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* - generate code to bootstrap subapp on client
*/

const assert = require("assert");
const Fs = require("fs");
const Path = require("path");
const _ = require("lodash");
Expand Down Expand Up @@ -53,7 +54,7 @@ module.exports = function setup(setupContext, { props: setupProps }) {
// name="Header"
// async=true
// defer=true
// streaming=true
// useStream=true
// serverSideRendering=true
// hydrateServerData=false
// clientSideRendering=false
Expand Down Expand Up @@ -189,10 +190,24 @@ Response: ${err || body}`
loadSubApp();
prepareSubAppJsBundle();

const verifyUseStream = props => {
if (props.useStream) {
const routeStream = setupContext.routeOptions.useStream;
assert(
routeStream !== false,
`subapp '${props.name}' can't set useStream when route options 'useStream' is false.`
);
}
};

verifyUseStream(setupProps);

const clientProps = JSON.stringify(_.pick(setupProps, ["useReactRouter"]));

return {
process: (context, { props }) => {
verifyUseStream(props);

const { request } = context.user;

if (request.app.webpackDev && subAppLoadTime < request.app.webpackDev.compileTime) {
Expand Down
9 changes: 3 additions & 6 deletions samples/poc-subapp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@ You can also control how your subapp works from server side to client side for e
Some of the attributes supported:

- `hydrate` - Enable client side hydration of initial state from server. ie: Use `React.hydrate` API.
- `streaming` - Use the streaming SSR APIs. ie: `ReactDomServer.renderToNodeStream`.
- `suspenseSsr` - Support suspense in SSR. No streaming.
- `useStream` - Use the stream SSR APIs. ie: `ReactDomServer.renderToNodeStream`.
- `suspenseSsr` - Support suspense in SSR. No stream support.

## React Router and SPA

Expand Down Expand Up @@ -195,10 +195,7 @@ const mapStateToProps = state => state;

export default reduxLoadSubApp({
name: "Home",
Component: connect(
mapStateToProps,
dispatch => ({ dispatch })
)(Home),
Component: connect(mapStateToProps, dispatch => ({ dispatch }))(Home),
reduxCreateStore(initialState) {
return createStore(reducers, initialState);
}
Expand Down
4 changes: 2 additions & 2 deletions samples/poc-subapp/TODO.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Streaming SSR [ ]
# Streaming SSR [x]

- Enable support for `renderToNodeStream`
- Enable HTTP streaming
Expand All @@ -11,7 +11,7 @@
- Store bundle load status in `window.webSubApps`
- When rendering subapp without bundle yet, dynamically load them

# Dynamic SSR [ ]
# Dynamic SSR [x]

- Allow each route and subapp to dynamically turn on/off SSR for a request

Expand Down
4 changes: 4 additions & 0 deletions samples/poc-subapp/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"use strict";
module.exports = {
extends: "@xarc/app-dev/config/babel/babelrc.js"
};
Loading