Skip to content

Commit ba15c01

Browse files
committed
Merge pull request #2 from combine/feature/devtools
add support for redux DevTools
2 parents 4221222 + 7955b9f commit ba15c01

File tree

14 files changed

+181
-118
lines changed

14 files changed

+181
-118
lines changed

client/index.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,7 @@ const rootElement = document.getElementById('app');
2727
// rendering.
2828
const history = __CORDOVA__ ? hashHistory : browserHistory;
2929
const initialState = window.__INITIAL_STATE__;
30-
const store = configureStore(initialState, {
31-
history: history,
32-
dispatchRouteChanges: true,
33-
rootElement: rootElement
34-
});
30+
const store = configureStore(initialState, history);
3531

3632
/* FastClick
3733
* Disables the 300ms delay for mobile apps. Comment out or add a conditional

common/config/store.dev.js

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { compose, createStore, applyMiddleware } from 'redux';
2+
import thunk from 'redux-thunk';
3+
import rootReducer from '../reducers';
4+
import persistState from 'redux-localstorage';
5+
import { syncHistory } from 'react-router-redux';
6+
import DevTools from '../shared/containers/DevTools';
7+
8+
/* localStorage Persisted States
9+
* Set up persisted state properties via localStorage. They should be added
10+
* by their property name of the piece of state you want to persist, e.g:
11+
* const persistedStates = ['session', 'order'];
12+
*/
13+
const persistedStates = [];
14+
15+
export default function configureStore(initialState, history = null) {
16+
/* Middleware
17+
* Configure this array with the middleware that you want included. thunk
18+
* is included by default, and react-router-redux's syncHistory is also
19+
* applied if an `options.history` object was passed to configureStore.
20+
*/
21+
let middleware = [thunk];
22+
23+
// Add universal enhancers here
24+
let enhancers = [
25+
DevTools.instrument()
26+
];
27+
28+
// Client-side enhancers and middleware
29+
if (isBrowser()) {
30+
enhancers.push(persistState(persistedStates));
31+
if (history) {
32+
middleware.push(syncHistory(history));
33+
}
34+
}
35+
36+
const enhancer = compose(...[
37+
applyMiddleware(...middleware),
38+
...enhancers
39+
]);
40+
41+
// create store with enhancers, middleware, reducers, and initialState
42+
const store = createStore(rootReducer, initialState, enhancer);
43+
44+
if (module.hot) {
45+
// Enable Webpack hot module replacement for reducers
46+
module.hot.accept('../reducers', () => {
47+
const nextRootReducer = require('../reducers').default;
48+
store.replaceReducer(nextRootReducer);
49+
});
50+
}
51+
52+
return store;
53+
}
54+
55+
function isBrowser() {
56+
return (typeof window !== 'undefined' && typeof window.document !== 'undefined');
57+
}

common/config/store.js

Lines changed: 4 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,5 @@
1-
import { compose, createStore, applyMiddleware } from 'redux';
2-
import thunk from 'redux-thunk';
3-
import rootReducer from '../reducers';
4-
import persistState from 'redux-localstorage';
5-
import { syncHistory } from 'react-router-redux';
6-
7-
export default function configureStore(initialState, options = {}) {
8-
const opts = Object.assign({}, {
9-
history: null,
10-
dispatchRouteChanges: false
11-
}, options);
12-
13-
14-
/* localStorage Persisted States
15-
* Set up persisted state properties via localStorage. They should be added
16-
* by their property name of the piece of state you want to persist, e.g:
17-
* const persistedStates = ['session', 'order'];
18-
*/
19-
const persistedStates = [];
20-
21-
/* Middleware
22-
* Configure this array with the middleware that you want included. thunk
23-
* is included by default, and react-router-redux's syncHistory is also
24-
* applied if an `options.history` object was passed to configureStore.
25-
*/
26-
const middleware = [
27-
// add more middlware here
28-
thunk
29-
].concat(
30-
opts.history ? [syncHistory(opts.history)] : []
31-
);
32-
33-
// Create an a composed method which enhances redux's createStore with
34-
// additional functionality
35-
let enhancers = [
36-
// Universal enhancers (both server and client-side)
37-
applyMiddleware.apply(this, middleware)
38-
39-
].concat(isBrowser() ? [
40-
// Add browser/client-side only enhancers here
41-
// e.g. localStorage, geolocation, etc.
42-
persistState(persistedStates)
43-
44-
] : [
45-
// Add server-side only enhancers here
46-
47-
]);
48-
49-
let enhanced = compose.apply(this, enhancers);
50-
51-
// create store with enhancers, middleware, reducers, and initialState
52-
const store = enhanced(createStore)(rootReducer, initialState);
53-
54-
if (module.hot) {
55-
// Enable Webpack hot module replacement for reducers
56-
module.hot.accept('../reducers', () => {
57-
const nextRootReducer = require('../reducers').default;
58-
store.replaceReducer(nextRootReducer);
59-
});
60-
}
61-
62-
return store;
63-
}
64-
65-
function isBrowser() {
66-
return (typeof window !== 'undefined' && typeof window.document !== 'undefined');
1+
if (process.env.NODE_ENV === 'production') {
2+
module.exports = require('./store.prod');
3+
} else {
4+
module.exports = require('./store.dev');
675
}

common/config/store.prod.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { compose, createStore, applyMiddleware } from 'redux';
2+
import thunk from 'redux-thunk';
3+
import rootReducer from '../reducers';
4+
import persistState from 'redux-localstorage';
5+
import { syncHistory } from 'react-router-redux';
6+
7+
/* localStorage Persisted States
8+
* Set up persisted state properties via localStorage. They should be added
9+
* by their property name of the piece of state you want to persist, e.g:
10+
* const persistedStates = ['session', 'order'];
11+
*/
12+
const persistedStates = [];
13+
14+
export default function configureStore(initialState, history = null) {
15+
/* Middleware
16+
* Configure this array with the middleware that you want included. thunk
17+
* is included by default, and react-router-redux's syncHistory is also
18+
* applied if an `options.history` object was passed to configureStore.
19+
*/
20+
let middleware = [thunk];
21+
22+
// Add universal enhancers here
23+
let enhancers = [];
24+
25+
// Client-side enhancers and middleware
26+
if (isBrowser()) {
27+
enhancers.push(persistState(persistedStates));
28+
if (history) {
29+
middleware.push(syncHistory(history));
30+
}
31+
}
32+
33+
const enhancer = compose(...[
34+
applyMiddleware(...middleware),
35+
...enhancers
36+
]);
37+
38+
// create store with enhancers, middleware, reducers, and initialState
39+
const store = createStore(rootReducer, initialState, enhancer);
40+
41+
return store;
42+
}
43+
44+
function isBrowser() {
45+
return (typeof window !== 'undefined' && typeof window.document !== 'undefined');
46+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import React, { Component } from 'react';
2+
import Header from '../components/Header';
3+
import Footer from '../components/Footer';
4+
import DevTools from '../../../shared/containers/DevTools';
5+
6+
export default class App extends Component {
7+
render() {
8+
const { header, footer } = this.props;
9+
return (
10+
<div>
11+
{header || <Header />}
12+
{this.props.children}
13+
{footer || <Footer />}
14+
<DevTools />
15+
</div>
16+
);
17+
}
18+
}

common/routes/app/containers/App.js

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,5 @@
1-
import React, { Component } from 'react';
2-
import Header from '../components/Header';
3-
import Footer from '../components/Footer';
4-
5-
export default class App extends Component {
6-
render() {
7-
const { header, footer } = this.props;
8-
return (
9-
<div>
10-
{header || <Header />}
11-
{this.props.children}
12-
{footer || <Footer />}
13-
</div>
14-
);
15-
}
1+
if (process.env.NODE_ENV === 'production') {
2+
module.exports = require('./App.prod');
3+
} else {
4+
module.exports = require('./App.dev');
165
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import React, { Component } from 'react';
2+
import Header from '../components/Header';
3+
import Footer from '../components/Footer';
4+
5+
export default class App extends Component {
6+
render() {
7+
const { header, footer } = this.props;
8+
return (
9+
<div>
10+
{header || <Header />}
11+
{this.props.children}
12+
{footer || <Footer />}
13+
</div>
14+
);
15+
}
16+
}

common/shared/containers/DevTools.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import React from 'react';
2+
3+
// Exported from redux-devtools
4+
import { createDevTools } from 'redux-devtools';
5+
6+
// Monitors are separate packages, and you can make a custom one
7+
import LogMonitor from 'redux-devtools-log-monitor';
8+
import DockMonitor from 'redux-devtools-dock-monitor';
9+
10+
// createDevTools takes a monitor and produces a DevTools component
11+
const DevTools = createDevTools(
12+
// Monitors are individually adjustable with props.
13+
// Consult their repositories to learn about those props.
14+
// Here, we put LogMonitor inside a DockMonitor.
15+
<DockMonitor toggleVisibilityKey="ctrl-h"
16+
changePositionKey="ctrl-q">
17+
<LogMonitor theme="tomorrow" />
18+
</DockMonitor>
19+
);
20+
21+
export default DevTools;

common/templates/server.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<link type="text/css" rel="stylesheet" href="<%= stylesheet %>" />
99
</head>
1010
<body>
11-
<div id="app" class="<%= appClass %>"><%= html %></div>
11+
<div id="app"><%= html %></div>
1212
<script>window.__INITIAL_STATE__ = <%= JSON.stringify(initialState) %>;</script>
1313
<script src="<%= bundleJs %>"></script>
1414
</body>

common/util/index.js

Lines changed: 0 additions & 18 deletions
This file was deleted.

nodemon.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
{
22
"watch": [
3-
"common/config/store.js",
43
"server/**/*.js",
54
"server/**/*.json",
65
"common/templates/server.html"

package.json

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,13 @@
4141
"cordova-lib": "6.0.0",
4242
"eslint": "1.10.3",
4343
"eslint-plugin-react": "3.16.1",
44-
"mocha": "2.4.4",
44+
"mocha": "2.4.5",
4545
"react-transform-catch-errors": "1.0.1",
4646
"react-transform-hmr": "1.0.1",
4747
"redbox-react": "1.2.0",
48+
"redux-devtools": "3.0.2",
49+
"redux-devtools-dock-monitor": "1.0.1",
50+
"redux-devtools-log-monitor": "1.0.2",
4851
"webpack-dev-server": "1.14.1",
4952
"yargs": "3.32.0"
5053
},
@@ -80,16 +83,14 @@
8083
"include-media": "1.4.1",
8184
"isomorphic-fetch": "2.2.1",
8285
"json-loader": "0.5.4",
83-
"lodash": "3.10.1",
86+
"lodash": "4.1.0",
8487
"node-sass": "3.4.2",
85-
"normalizr": "1.4.1",
86-
"react": "0.14.6",
87-
"react-dom": "0.14.6",
88-
"react-redux": "4.1.0",
88+
"react": "0.14.7",
89+
"react-dom": "0.14.7",
90+
"react-redux": "4.1.2",
8991
"react-router": "2.0.0-rc5",
9092
"react-router-redux": "2.1.0",
91-
"react-select": "0.9.1",
92-
"redux": "3.0.6",
93+
"redux": "3.1.4",
9394
"redux-localstorage": "0.4.0",
9495
"redux-thunk": "1.0.3",
9596
"reselect": "2.0.2",

server/server.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import ReactDOMServer from 'react-dom/server';
55
import { Provider } from 'react-redux';
66
import { RouterContext, match } from 'react-router';
77
import { routes } from '../common/routes';
8-
import { rootPath } from '../common/util';
98
import createLocation from 'history/lib/createLocation';
109
import config from './config';
1110
import configureStore from '../common/config/store';
@@ -88,15 +87,13 @@ function renderFullPage(html, initialState, renderProps) {
8887
let favicon = assets['./common/assets/images/favicon.png'];
8988
let stylesheet = assetHost + 'styles.css';
9089
let bundleJs = assetHost + 'bundle.js';
91-
let appClass = rootPath(renderProps.location.pathname);
9290
return compiledTemplate({
9391
html,
9492
title,
9593
favicon,
9694
stylesheet,
9795
bundleJs,
98-
initialState,
99-
appClass: appClass ? 'page-' + appClass : null
96+
initialState
10097
});
10198
}
10299

webpack/config.development.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ var plugins = (hot ? [
2626
// this should always be last so it can be replaceable by config.cordova.js or
2727
// something else that overrides it
2828
new webpack.DefinePlugin({
29+
'process.env': {
30+
'NODE_ENV': JSON.stringify('development')
31+
},
2932
'__CORDOVA__': false,
3033
'__PRODUCTION__': false,
3134
'__DEVELOPMENT__': true,

0 commit comments

Comments
 (0)