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

Commit

Permalink
Moved async dependency to ContextHelper. Added 'src' to webpack modul…
Browse files Browse the repository at this point in the history
…esDirectories.
  • Loading branch information
RickWong committed Mar 15, 2015
1 parent 87b0fbc commit 23f171f
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 34 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"scripts": {
"start": "supervisor dist/server",
"localhost": "sleep 1; which open && open http://localhost:8000",
"browser": "sleep 6; concurrent 'npm run start' 'npm run localhost'",
"browser": "sleep 6; concurrent --kill-others 'npm run start' 'npm run localhost'",
"build-server": "webpack --verbose --colors --display-error-details --config webpack.server.js",
"build-client": "webpack --verbose --colors --display-error-details --config webpack.client.js",
"build": "concurrent 'npm run build-client' 'npm run build-server'",
Expand Down
11 changes: 6 additions & 5 deletions src/client.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from "react";
import Router from "react-router";
import ContextHelper from "./helpers/ContextHelper";
import routes from "./views/Routes";
import ContextHelper from "helpers/ContextHelper";
import routes from "views/Routes";

/**
* Enable Accessibility warnings on the client.
Expand All @@ -17,10 +17,11 @@ Router.run(routes, Router.HistoryLocation, (Handler) => {
/**
* Get Client Context passed along by the server, and inject it.
*/
const clientContext = ContextHelper.getClientContext(window);
const ContextualHandler = ContextHelper.injectContext(Handler, clientContext);
const context = ContextHelper.getClientContext(window);

React.render(<ContextualHandler />, document.getElementById("react-root"));
ContextHelper.injectContext(Handler, context, (ContextualHandler) => {
React.render(<ContextualHandler />, document.getElementById("react-root"));
});
});

/**
Expand Down
22 changes: 19 additions & 3 deletions src/helpers/ContextHelper.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Async from "async";
import React from "react";

/**
Expand All @@ -17,7 +18,7 @@ const ContextMixin = {
},
getContext (key) {
if (!this.context) {
return null;
return undefined;
}

if (key === undefined) {
Expand Down Expand Up @@ -45,14 +46,14 @@ const ContextHelper = {
(k) => context.contextLoaders[k]
);
},
injectContext (Component, context) {
injectContext (Component, context, callbackFn) {
let childContextTypes = {};

Object.keys(context).map((key) => {
childContextTypes[key] = React.PropTypes.any
});

return React.createClass({
const ContextualComponent = React.createClass({
childContextTypes,
getChildContext () {
return context;
Expand All @@ -61,6 +62,21 @@ const ContextHelper = {
return <Component />;
}
});

if (__CLIENT__) {
callbackFn(ContextualComponent);
return;
}

/**
* Fake-render the components without output so they can register context loaders.
*/
React.renderToString(<ContextualComponent />);
const contextLoaders = ContextHelper.getContextLoaders(context);

Async.parallel(contextLoaders, (error, result) => {
callbackFn(ContextualComponent);
});
},
getServerContext () {
let serverContext = {};
Expand Down
34 changes: 14 additions & 20 deletions src/server.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import async from "async";
import {Server} from "hapi";
import React from "react";
import Router from "react-router";
import ContextHelper from "./helpers/ContextHelper";
import routes from "./views/Routes";
import ContextHelper from "helpers/ContextHelper";
import routes from "views/Routes";

/**
* Start Hapi server on port 8000.
Expand Down Expand Up @@ -33,29 +32,23 @@ server.ext("onPreResponse", (request, reply) => {
return reply.continue();
}

Router.run(routes, request.path, (Handler) => {
Router.run(routes, request.path, (Handler, router) => {
/**
* Prepare a unique Server Context per request, and inject it.
*/
const serverContext = ContextHelper.getServerContext();
serverContext.request = request;
const ContextualHandler = ContextHelper.injectContext(Handler, serverContext);
const context = ContextHelper.getServerContext();
context.request = request;
context.router = router;

/**
* Fake-render the components without output so they can register context loaders.
*/
React.renderToString(<ContextualHandler />);
const loaders = ContextHelper.getContextLoaders(serverContext);

/**
* Wait for all the registered callbacks and render for real, but this time with data.
*/
async.parallel(loaders, (error, results) => {
ContextHelper.injectContext(Handler, context, (ContextualHandler) => {
/**
* Wait for all the registered callbacks and render for real, but this time with data.
*/
const rendered = React.renderToString(<ContextualHandler />);
const contextData = JSON.stringify(serverContext.contextData);
const contextData = JSON.stringify(context.contextData);
const webserver = process.env.NODE_ENV === "production" ? "" : "//localhost:8080";

const output =
const output = (
`<!doctype html>
<html lang="en-us">
<head>
Expand All @@ -68,7 +61,8 @@ server.ext("onPreResponse", (request, reply) => {
<script>window.CONTEXT_DATA = ${contextData};</script>
<script src="${webserver}/dist/client.js"></script>
</body>
</html>`;
</html>`
);

reply(output);
});
Expand Down
6 changes: 4 additions & 2 deletions src/views/Main.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import React from "react";
import InlineCss from "react-inline-css";
import Superagent from "superagent";
import ContextHelper from "../helpers/ContextHelper";
import ContextHelper from "helpers/ContextHelper";

/**
* Main React application entry-point for both the server and client.
*
* @class Main
*/
export default React.createClass({
const Main = React.createClass({
mixins: [
ContextHelper.Mixin
],
Expand Down Expand Up @@ -151,3 +151,5 @@ export default React.createClass({
);
}
});

export default Main;
2 changes: 1 addition & 1 deletion src/views/Routes.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";
import Router, {Route, DefaultRoute} from "react-router";
import Main from "./Main";
import Main from "views/Main";

/**
* The React Routes for both the server and the client.
Expand Down
9 changes: 9 additions & 0 deletions webpack.client.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ module.exports = {
]
},
resolve: {
modulesDirectories: [
"src",
"node_modules",
"web_modules"
],
extensions: ["", ".json", ".jsx", ".js"]
},
node: {
__dirname: true,
fs: 'empty'
}
};
8 changes: 6 additions & 2 deletions webpack.server.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,14 @@ module.exports = {
]
},
resolve: {
modulesDirectories: [
"src",
"node_modules",
"web_modules"
],
extensions: ["", ".json", ".jsx", ".js"]
},
node: {
__dirname: true,
fs: 'empty'
__dirname: true
}
};

0 comments on commit 23f171f

Please sign in to comment.