Add webpack cold reloading
On changes to the react bundle webpack will store the current redux state in localStorage, waits (to allow the server to restart) then refreshes the page. On page load, it checks if it has state stored and loads it into the app.
This commit is contained in:
@@ -6,7 +6,7 @@ import { Router } from 'react-router';
|
||||
import { routeReducer as routing, syncHistory } from 'react-router-redux';
|
||||
import { createHistory } from 'history';
|
||||
|
||||
import app$ from '../common/app';
|
||||
import createApp from '../common/app';
|
||||
import provideStore from '../common/app/provide-store';
|
||||
|
||||
// client specific sagas
|
||||
@@ -14,20 +14,26 @@ import sagas from './sagas';
|
||||
|
||||
// render to observable
|
||||
import render from '../common/app/utils/render';
|
||||
import {
|
||||
isColdStored,
|
||||
getColdStorage,
|
||||
saveToColdStorage
|
||||
} from './cold-reload';
|
||||
|
||||
Rx.config.longStackSupport = !!debug.enabled;
|
||||
|
||||
const log = debug('fcc:client');
|
||||
const DOMContainer = document.getElementById('fcc');
|
||||
const initialState = window.__fcc__.data;
|
||||
const hotReloadTimeout = 5000;
|
||||
const csrfToken = window.__fcc__.csrf.token;
|
||||
const initialState = isColdStored() ?
|
||||
getColdStorage() :
|
||||
window.__fcc__.data;
|
||||
initialState.app.csrfToken = csrfToken;
|
||||
|
||||
const serviceOptions = { xhrPath: '/services', context: { _csrf: csrfToken } };
|
||||
|
||||
Rx.config.longStackSupport = !!debug.enabled;
|
||||
const history = createHistory();
|
||||
const appLocation = history.createLocation(
|
||||
location.pathname + location.search
|
||||
);
|
||||
const routingMiddleware = syncHistory(history);
|
||||
|
||||
const devTools = window.devToolsExtension ? window.devToolsExtension() : f => f;
|
||||
@@ -35,37 +41,35 @@ const shouldRouterListenForReplays = !!window.devToolsExtension;
|
||||
|
||||
const clientSagaOptions = { doc: document };
|
||||
|
||||
// returns an observable
|
||||
app$({
|
||||
location: appLocation,
|
||||
history,
|
||||
serviceOptions,
|
||||
initialState,
|
||||
middlewares: [
|
||||
routingMiddleware,
|
||||
...sagas.map(saga => saga(clientSagaOptions))
|
||||
],
|
||||
reducers: { routing },
|
||||
enhancers: [ devTools ]
|
||||
})
|
||||
.flatMap(({ props, store }) => {
|
||||
|
||||
// because of weirdness in react-routers match function
|
||||
// we replace the wrapped returned in props with the first one
|
||||
// we passed in. This might be fixed in react-router 2.0
|
||||
props.history = history;
|
||||
|
||||
createApp({
|
||||
history,
|
||||
serviceOptions,
|
||||
initialState,
|
||||
middlewares: [
|
||||
routingMiddleware,
|
||||
...sagas.map(saga => saga(clientSagaOptions))
|
||||
],
|
||||
reducers: { routing },
|
||||
enhancers: [ devTools ]
|
||||
})
|
||||
.doOnNext(({ store }) => {
|
||||
if (shouldRouterListenForReplays && store) {
|
||||
log('routing middleware listening for replays');
|
||||
routingMiddleware.listenForReplays(store);
|
||||
}
|
||||
|
||||
log('rendering');
|
||||
return render(
|
||||
provideStore(React.createElement(Router, props), store),
|
||||
DOMContainer
|
||||
);
|
||||
if (module.hot && typeof module.hot.accept === 'function') {
|
||||
module.hot.accept('../common/app', function() {
|
||||
saveToColdStorage(store.getState());
|
||||
setTimeout(() => window.location.reload(), hotReloadTimeout);
|
||||
});
|
||||
}
|
||||
})
|
||||
.doOnNext(() => log('rendering'))
|
||||
.flatMap(({ props, store }) => render(
|
||||
provideStore(React.createElement(Router, props), store),
|
||||
DOMContainer
|
||||
))
|
||||
.subscribe(
|
||||
() => debug('react rendered'),
|
||||
err => { throw err; },
|
||||
|
Reference in New Issue
Block a user