freeCodeCamp/server/boot/a-react.js

82 lines
2.1 KiB
JavaScript
Raw Normal View History

import React from 'react';
2015-09-13 18:12:22 -07:00
import { RoutingContext } from 'react-router';
import { createLocation } from 'history';
2016-01-27 11:34:44 -08:00
import debug from 'debug';
import renderToString from '../../common/app/utils/render-to-string';
import provideStore from '../../common/app/provide-store';
2015-12-22 19:28:07 -08:00
2016-01-06 09:33:55 -08:00
import app$ from '../../common/app';
2015-06-29 09:50:25 -07:00
2016-01-27 11:34:44 -08:00
const log = debug('fcc:react-server');
2015-07-01 15:14:10 -07:00
// add routes here as they slowly get reactified
// remove their individual controllers
2015-06-29 12:01:56 -07:00
const routes = [
2015-08-31 09:53:25 -07:00
'/jobs',
2015-12-22 19:28:07 -08:00
'/jobs/*',
'/videos',
'/videos/*'
2015-10-19 23:16:56 -07:00
];
2015-12-22 19:28:07 -08:00
const devRoutes = [];
2015-06-29 12:01:56 -07:00
export default function reactSubRouter(app) {
2015-07-02 23:44:34 -07:00
var router = app.loopback.Router();
2015-06-29 09:50:25 -07:00
2015-10-29 17:55:42 -07:00
// These routes are in production
routes.forEach((route) => {
router.get(route, serveReactApp);
});
2015-10-19 23:16:56 -07:00
2015-08-13 11:09:34 -07:00
if (process.env.NODE_ENV === 'development') {
2015-10-19 23:16:56 -07:00
devRoutes.forEach(function(route) {
2015-08-13 11:09:34 -07:00
router.get(route, serveReactApp);
});
}
2015-06-29 09:50:25 -07:00
app.use(router);
function serveReactApp(req, res, next) {
2016-01-27 11:34:44 -08:00
const serviceOptions = { req };
2015-09-13 18:12:22 -07:00
const location = createLocation(req.path);
2015-06-29 09:50:25 -07:00
// returns a router wrapped app
2016-01-27 11:34:44 -08:00
app$({
location,
serviceOptions
})
2015-06-29 09:50:25 -07:00
// if react-router does not find a route send down the chain
2016-01-27 11:34:44 -08:00
.filter(({ props }) => {
2015-09-13 18:12:22 -07:00
if (!props) {
2016-01-27 11:34:44 -08:00
log(`react tried to find ${location.pathname} but got 404`);
2015-07-03 21:46:22 -07:00
return next();
2015-06-29 09:50:25 -07:00
}
2015-09-13 18:12:22 -07:00
return !!props;
2015-06-29 09:50:25 -07:00
})
2016-01-27 11:34:44 -08:00
.flatMap(({ props, store }) => {
log('render react markup and pre-fetch data');
2016-01-03 19:40:49 -08:00
2016-01-27 11:34:44 -08:00
return renderToString(
provideStore(React.createElement(RoutingContext, props), store)
2015-12-22 19:28:07 -08:00
)
2016-01-27 11:34:44 -08:00
.map(({ markup }) => ({ markup, store }));
2015-06-29 09:50:25 -07:00
})
2016-01-27 11:34:44 -08:00
.flatMap(function({ markup, store }) {
log('react markup rendered, data fetched');
const state = store.getState();
const { title } = state.app.title;
res.expose(state, 'data');
return res.render$(
'layout-react',
{ markup, title }
);
2015-06-29 09:50:25 -07:00
})
2016-01-27 11:34:44 -08:00
.doOnNext(markup => res.send(markup))
2015-06-29 09:50:25 -07:00
.subscribe(
2016-01-27 11:34:44 -08:00
() => log('html rendered and ready to send'),
2015-06-29 09:50:25 -07:00
next
);
}
2015-06-29 12:01:56 -07:00
}