Isomorphic server.js
import express from 'express';
import bodyParser from 'body-parser';
import path from 'path';
import session from 'express-session';
import axios from 'axios';
import React from 'react';
import { renderToString } from 'react-dom/server'
import { RouterContext, match } from 'react-router';
import { Provider } from 'react-redux';
import routes from 'routes';
import * as reducers from 'redux/reducers';
import favicon from 'serve-favicon';
import promiseMiddleware from 'lib/promiseMiddleware';
import fetchComponentData from 'lib/fetchComponentData';
import { createStore,
combineReducers,
applyMiddleware,
compose } from 'redux';
import apiRouter from './api';
import config from './config';
import Html from './helpers/Html';
Object.assign = require('object-assign');
const app = express();
if (__DEVELOPMENT__) {
require('../../webpack/webpack.dev').default(app);
}
app.use(favicon(path.join(__dirname, '..', '..', 'static', 'favicon.ico')));
app.use(express.static(path.join(__dirname, '..', '..', 'static'), { maxAge: '7 days' }));
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
app.use(config.apiBaseUrl, apiRouter);
app.use((req, res) => {
if (__DEVELOPMENT__) {
global.webpackIsomorphicTools.refresh();
}
res.contentType('text/html');
const isoAssets = global.webpackIsomorphicTools.assets();
// isoAssets is the object I would like to pass in redux store
const reducer = combineReducers(reducers);
const store = applyMiddleware(promiseMiddleware)(createStore)(reducer);
match({routes, location: req.url}, (err, redirectLocation, renderProps) => {
if (err) {
console.error(err);
return res.status(500).end('Internal server error');
}
if (redirectLocation) {
return res.redirect(302, redirectLocation.pathname + redirectLocation.search);
}
if (!renderProps)
return res.status(404).end('Not found');
function renderView(errOrArrayFromPromiseAll) {
const createElement = (Component, props) => (
<Component
{...props}
radiumConfig={{ userAgent: req.headers['user-agent'] }}
/>
);
//pass into redux state..
const InitialView = (
<Provider store={store}>
<RouterContext
{...renderProps}
createElement={createElement} />
</Provider>
);
const componentHTML = renderToString(InitialView);
const HTML = '<!doctype html>\n' +
renderToString(<Html assets={global.webpackIsomorphicTools.assets()} componentHtml={componentHTML} store={store}/>);
return HTML;
}
fetchComponentData(store.dispatch, renderProps.components, renderProps.params)
.then(renderView)
.then(html => res.end(html))
.catch(err => res.end(err.message));
});
});
export default app;
import 'babel-polyfill';
import React from 'react';
import { render } from 'react-dom';
import {
Router,
browserHistory,
} from 'react-router';
import { createHistory } from 'history'
import { Provider } from 'react-redux';
import * as reducers from 'redux/reducers';
import routes from 'routes';
import axios from 'axios';
import promiseMiddleware from 'lib/promiseMiddleware';
import immutifyState from 'lib/immutifyState';
import { createStore,
combineReducers,
applyMiddleware,
compose } from 'redux';
const initialState = immutifyState(window.__INITIAL_STATE__);
const reducer = combineReducers(reducers);
const store = applyMiddleware(promiseMiddleware)(createStore)(reducer, initialState, compose(
window.devToolsExtension ? window.devToolsExtension() : f => f
));
const history = createHistory();
render(
<Provider store={store}>
<Router history={history} children={routes} />
</Provider>,
document.getElementById('react-view')
);