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

first step at supporting SSR for preact+redux-bundler #1506

Merged
merged 1 commit into from
Jan 22, 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
94 changes: 47 additions & 47 deletions packages/subapp-pbundle/lib/framework-lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

/* eslint-disable max-statements */

const assert = require("assert");
const preact = require("preact");
const { default: AppContext } = require("../dist/node/app-context");
const prts = require("preact-render-to-string");
const { Provider } = require("redux-bundler-preact");

class FrameworkLib {
constructor(ref) {
Expand All @@ -24,7 +26,7 @@ class FrameworkLib {
if (!this.StartComponent) {
return `<!-- serverSideRendering ${subApp.name} has no StartComponent -->`;
} else if (subApp.__redux) {
// return await this.doReduxSSR();
return await this.doReduxBundlerSSR();
} else if (options.serverSideRendering === true) {
return await this.doSSR();
}
Expand Down Expand Up @@ -89,52 +91,50 @@ class FrameworkLib {
return await this.renderTo(this.createTopComponent(initialProps), this.ref.options);
}

// TODO for redux-bundler

// async doReduxSSR() {
// const { subApp, subAppServer, context, options } = this.ref;
// const { request } = context.user;
// // subApp.reduxReducers || subApp.reduxCreateStore) {
// // if sub app has reduxReducers or reduxCreateStore then assume it's using
// // redux data model. prepare initial state and store to render it.
// let reduxData;

// // see if app has a prepare callback, on the server side first, and then the
// // app itself, and call it. assume the object it returns would contain the
// // initial redux state data.
// const prepare = subAppServer.prepare || subApp.prepare;
// if (prepare) {
// reduxData = await prepare({ request, context });
// }

// if (!reduxData) {
// reduxData = { initialState: {} };
// }

// this.initialState = reduxData.initialState || reduxData;
// // if subapp didn't request to skip sending initial state, then stringify it
// // and attach it to the index html.
// if (subAppServer.attachInitialState !== false) {
// this.initialStateStr = JSON.stringify(this.initialState);
// }
// // next we take the initial state and create redux store from it
// this.store =
// reduxData.store ||
// (subApp.reduxCreateStore && (await subApp.reduxCreateStore(this.initialState)));
// assert(
// this.store,
// `redux subapp ${subApp.name} didn't provide store, reduxCreateStore, or reducers`
// );
// if (options.serverSideRendering === true) {
// assert(Provider, "subapp-web: react-redux Provider not available");
// // finally render the element with Redux Provider and the store created
// return await this.renderTo(
// preact.createElement(Provider, { store: this.store }, this.createTopComponent()),
// options
// );
// }
// return "";
// }
async doReduxBundlerSSR() {
const { subApp, subAppServer, context, options } = this.ref;
const { request } = context.user;
// subApp.reduxReducers || subApp.reduxCreateStore) {
// if sub app has reduxReducers or reduxCreateStore then assume it's using
// redux data model. prepare initial state and store to render it.
let reduxData;

// see if app has a prepare callback, on the server side first, and then the
// app itself, and call it. assume the object it returns would contain the
// initial redux state data.
const prepare = subAppServer.prepare || subApp.prepare;
if (prepare) {
reduxData = await prepare({ request, context });
}

if (!reduxData) {
reduxData = { initialState: {} };
}

this.initialState = reduxData.initialState || reduxData;
// if subapp didn't request to skip sending initial state, then stringify it
// and attach it to the index html.
if (subAppServer.attachInitialState !== false) {
this.initialStateStr = JSON.stringify(this.initialState);
}
// next we take the initial state and create redux store from it
this.store =
reduxData.store ||
(subApp.reduxCreateStore && (await subApp.reduxCreateStore(this.initialState)));
assert(
this.store,
`redux subapp ${subApp.name} didn't provide store, reduxCreateStore, or reducers`
);
if (options.serverSideRendering === true) {
assert(Provider, "subapp-web: react-redux Provider not available");
// finally render the element with Redux Provider and the store created
return await this.renderTo(
preact.createElement(Provider, { store: this.store }, this.createTopComponent()),
options
);
}
return "";
}
}

module.exports = FrameworkLib;
1 change: 1 addition & 0 deletions packages/subapp-pbundle/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
],
"dependencies": {
"@babel/runtime": "^7.8.3",
"redux-bundler-preact": "^2.0.1",
"subapp-util": "^1.0.2",
"subapp-web": "^1.0.11"
},
Expand Down
6 changes: 5 additions & 1 deletion samples/poc-subapp-pmin/src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ export default {
// an object of options, ie: [ "./home", {serverSideRendering: true } ]
// Ultimately, the resolved path will uniquely identify the subapp
// TBD: A subapp could potentially be loaded from a remote URL.
subApps: ["./home", ["./demo1", { serverSideRendering: false }]],
subApps: [
"./home",
["./demo1", { serverSideRendering: false }],
["./demo1", { serverSideRendering: true }]
],

/* templateFile */
// - path your own index page template
Expand Down