From 88b4b6e9dbe1e5e4d387d611747957e452867517 Mon Sep 17 00:00:00 2001 From: Fredrik Lindell Date: Wed, 24 May 2017 21:36:36 +0200 Subject: [PATCH 1/9] Update packages and webpack config * Update packages and webpack config --- package.json | 64 +++++++++++++++++++++++-------------------- webpack.config.dev.js | 9 +++--- 2 files changed, 39 insertions(+), 34 deletions(-) diff --git a/package.json b/package.json index a92abed..6453490 100644 --- a/package.json +++ b/package.json @@ -18,38 +18,42 @@ "license": "MIT", "homepage": "https://github.com/tsaiDavid/simple-redux-boilerplate", "devDependencies": { - "autoprefixer": "^6.3.1", - "babel-core": "^6.3.15", - "babel-eslint": "^5.0.0-beta4", - "babel-loader": "^6.2.0", - "babel-preset-es2015": "^6.3.13", - "babel-preset-react": "^6.3.13", - "babel-preset-react-hmre": "^1.0.0", - "cross-env": "^1.0.6", - "css-loader": "^0.23.1", - "eslint": "^1.10.3", - "eslint-config-airbnb": "^4.0.0", - "eslint-plugin-babel": "^3.0.0", - "eslint-plugin-react": "^3.16.1", + "autoprefixer": "^7.1.1", + "babel-core": "^6.24.1", + "babel-eslint": "^7.2.3", + "babel-loader": "^7.0.0", + "babel-preset-es2015": "^6.24.1", + "babel-preset-react": "^6.24.1", + "babel-preset-react-hmre": "^1.1.1", + "cross-env": "^5.0.0", + "css-loader": "^0.28.2", + "eslint": "^3.19.0", + "eslint-config-airbnb": "^15.0.1", + "eslint-plugin-babel": "^4.1.1", + "eslint-plugin-import": "^2.3.0", + "eslint-plugin-jsx-a11y": "^5.0.3", + "eslint-plugin-react": "^7.0.1", "eventsource-polyfill": "^0.9.6", - "express": "^4.13.3", - "html-webpack-plugin": "^2.24.1", - "node-sass": "^3.4.2", - "redux-devtools": "^3.0.1", - "redux-devtools-dock-monitor": "^1.0.1", - "redux-devtools-log-monitor": "^1.0.2", - "redux-logger": "^2.4.0", - "rimraf": "^2.4.3", - "sass-loader": "^3.1.2", - "style-loader": "^0.13.0", - "webpack": "^1.12.12", - "webpack-dev-middleware": "^1.4.0", - "webpack-hot-middleware": "^2.6.0" + "express": "^4.15.3", + "html-webpack-plugin": "^2.28.0", + "node-sass": "^4.5.3", + "redux-devtools": "^3.4.0", + "redux-devtools-dock-monitor": "^1.1.2", + "redux-devtools-log-monitor": "^1.3.0", + "rimraf": "^2.6.1", + "sass-loader": "^6.0.5", + "style-loader": "^0.18.1", + "webpack": "^2.6.0", + "webpack-dev-middleware": "^1.10.2", + "webpack-hot-middleware": "^2.18.0" }, "dependencies": { - "react": "^0.14.3", - "react-dom": "^0.14.3", - "react-redux": "^4.1.1", - "redux-thunk": "^1.0.3" + "prop-types": "^15.5.10", + "react": "^15.5.4", + "react-dom": "^15.5.4", + "react-redux": "^5.0.5", + "redux": "^3.6.0", + "redux-logger": "^3.0.6", + "redux-thunk": "^2.2.0" } } diff --git a/webpack.config.dev.js b/webpack.config.dev.js index 7a936ae..98da0aa 100644 --- a/webpack.config.dev.js +++ b/webpack.config.dev.js @@ -7,7 +7,7 @@ module.exports = { entry: [ 'eventsource-polyfill', // necessary for hot reloading with IE 'webpack-hot-middleware/client', - './src/index' + './src/index.jsx' ], output: { path: path.join(__dirname, 'dist'), @@ -25,7 +25,8 @@ module.exports = { * will not be emitted. If you want your webpack to 'fail', you need to check out * the bail option. */ - new webpack.NoErrorsPlugin(), +// new webpack.NoErrorsPlugin(), + new webpack.NoEmitOnErrorsPlugin(), /** * This is a webpack plugin that simplifies creation of HTML files to serve your * webpack bundles. This is especially useful for webpack bundles that @@ -51,12 +52,12 @@ module.exports = { { test: /\.js?/, exclude: [/node_modules/, /styles/], - loaders: ['babel'], + loaders: ['babel-loader'], include: path.join(__dirname, 'src') }, { test: /\.scss$/, - loader: 'style!css!sass' + loader: 'style-loader!css-loader!sass-loader' } ] } From 232d6458bdc7554f59e00be05be0393c08c4de36 Mon Sep 17 00:00:00 2001 From: Fredrik Lindell Date: Wed, 24 May 2017 21:38:18 +0200 Subject: [PATCH 2/9] Fixing lint errors * Fixing lint errors --- src/actions/CounterActions.js | 2 +- src/reducers/counter.js | 12 ++++++------ src/store/configureStore.dev.js | 4 ++-- src/store/configureStore.prod.js | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/actions/CounterActions.js b/src/actions/CounterActions.js index 9ddaa83..2da0891 100644 --- a/src/actions/CounterActions.js +++ b/src/actions/CounterActions.js @@ -25,7 +25,7 @@ export function incrementIfOdd() { } export function incrementAsync() { - return dispatch => { + return (dispatch) => { setTimeout(() => { dispatch(increment()); }, 1000); diff --git a/src/reducers/counter.js b/src/reducers/counter.js index 94b6dfa..a23a1c7 100644 --- a/src/reducers/counter.js +++ b/src/reducers/counter.js @@ -2,11 +2,11 @@ import { INCREMENT_COUNTER, DECREMENT_COUNTER } from '../constants/ActionTypes'; export default function counter(state = 0, action) { switch (action.type) { - case INCREMENT_COUNTER: - return state + 1; - case DECREMENT_COUNTER: - return state - 1; - default: - return state; + case INCREMENT_COUNTER: + return state + 1; + case DECREMENT_COUNTER: + return state - 1; + default: + return state; } } diff --git a/src/store/configureStore.dev.js b/src/store/configureStore.dev.js index 0091373..ef3bbc4 100644 --- a/src/store/configureStore.dev.js +++ b/src/store/configureStore.dev.js @@ -1,8 +1,8 @@ import { createStore, applyMiddleware, compose } from 'redux'; -import rootReducer from '../reducers'; -import createLogger from 'redux-logger'; +import { createLogger } from 'redux-logger'; import thunk from 'redux-thunk'; import DevTools from '../containers/DevTools'; +import rootReducer from '../reducers'; /** * Entirely optional, this tiny library adds some functionality to diff --git a/src/store/configureStore.prod.js b/src/store/configureStore.prod.js index dca1697..5b3d6f8 100644 --- a/src/store/configureStore.prod.js +++ b/src/store/configureStore.prod.js @@ -1,6 +1,6 @@ import { createStore, applyMiddleware, compose } from 'redux'; -import rootReducer from '../reducers'; import thunk from 'redux-thunk'; +import rootReducer from '../reducers'; const finalCreateStore = compose( applyMiddleware(thunk) From ff05494e40679b03e54a93fcc0aa95e97b7c98a2 Mon Sep 17 00:00:00 2001 From: Fredrik Lindell Date: Wed, 24 May 2017 21:42:28 +0200 Subject: [PATCH 3/9] Change PropTypes to prop-types package * Change PropTypes to prop-types package --- src/components/Counter.js | 3 ++- src/containers/App.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/Counter.js b/src/components/Counter.js index 3fd02ec..8cc1456 100644 --- a/src/components/Counter.js +++ b/src/components/Counter.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from 'react'; +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; export default class Counter extends Component { constructor(props, context) { diff --git a/src/containers/App.js b/src/containers/App.js index 93d795e..030092f 100644 --- a/src/containers/App.js +++ b/src/containers/App.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from 'react'; +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; import { bindActionCreators } from 'redux'; import { connect } from 'react-redux'; import * as CounterActions from '../actions/CounterActions'; From 062bc8f1a1d2a6b15bb7176fc9d548f67268ab06 Mon Sep 17 00:00:00 2001 From: Fredrik Lindell Date: Wed, 24 May 2017 21:43:05 +0200 Subject: [PATCH 4/9] Update introduced bug in webpack dev conf * Change PropTypes to prop-types package --- webpack.config.dev.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webpack.config.dev.js b/webpack.config.dev.js index 98da0aa..825a415 100644 --- a/webpack.config.dev.js +++ b/webpack.config.dev.js @@ -7,7 +7,7 @@ module.exports = { entry: [ 'eventsource-polyfill', // necessary for hot reloading with IE 'webpack-hot-middleware/client', - './src/index.jsx' + './src/index' ], output: { path: path.join(__dirname, 'dist'), From cf32399947ff479db403cf1329fa96074e79b3e4 Mon Sep 17 00:00:00 2001 From: Fredrik Lindell Date: Wed, 24 May 2017 21:51:13 +0200 Subject: [PATCH 5/9] Updated webpack prod conf * Updated webpack prod conf --- webpack.config.prod.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/webpack.config.prod.js b/webpack.config.prod.js index 20d21ee..99e1976 100644 --- a/webpack.config.prod.js +++ b/webpack.config.prod.js @@ -10,7 +10,7 @@ module.exports = { output: { path: path.join(__dirname, 'dist'), filename: '[name]-[hash].js', - publicPath: '/' + publicPath: './' }, plugins: [ /** @@ -18,7 +18,7 @@ module.exports = { * means is that frequently used IDs will get lower/shorter IDs - so they become * more predictable. */ - new webpack.optimize.OccurenceOrderPlugin(), + new webpack.optimize.OccurrenceOrderPlugin(), /** * This is a webpack plugin that simplifies creation of HTML files to serve your * webpack bundles. This is especially useful for webpack bundles that @@ -51,12 +51,12 @@ module.exports = { loaders: [ { test: /\.js$/, - loaders: ['babel'], + loaders: ['babel-loader'], include: path.join(__dirname, 'src') }, { test: /\.scss$/, - loader: 'style!css!sass' + loader: 'style-loader!css-loader!sass-loader' } ] } From 81783272821097d68529db4682f24606e8498e81 Mon Sep 17 00:00:00 2001 From: Fredrik Lindell Date: Wed, 24 May 2017 21:58:30 +0200 Subject: [PATCH 6/9] Fixed a bunch of lint errors * Fixed a bunch of lint errors --- package.json | 6 +++--- src/components/Counter.js | 7 ++----- src/containers/DevTools.js | 6 ++++-- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 6453490..4d38eda 100644 --- a/package.json +++ b/package.json @@ -37,9 +37,6 @@ "express": "^4.15.3", "html-webpack-plugin": "^2.28.0", "node-sass": "^4.5.3", - "redux-devtools": "^3.4.0", - "redux-devtools-dock-monitor": "^1.1.2", - "redux-devtools-log-monitor": "^1.3.0", "rimraf": "^2.6.1", "sass-loader": "^6.0.5", "style-loader": "^0.18.1", @@ -53,6 +50,9 @@ "react-dom": "^15.5.4", "react-redux": "^5.0.5", "redux": "^3.6.0", + "redux-devtools": "^3.4.0", + "redux-devtools-dock-monitor": "^1.1.2", + "redux-devtools-log-monitor": "^1.3.0", "redux-logger": "^3.0.6", "redux-thunk": "^2.2.0" } diff --git a/src/components/Counter.js b/src/components/Counter.js index 8cc1456..53b87a6 100644 --- a/src/components/Counter.js +++ b/src/components/Counter.js @@ -2,9 +2,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; export default class Counter extends Component { - constructor(props, context) { - super(props, context); - } handleIncrement() { this.props.actions.increment(); @@ -24,8 +21,8 @@ export default class Counter extends Component {
{this.props.counter % 2 === 0 ? 'even' : 'odd'}

- - + +
); diff --git a/src/containers/DevTools.js b/src/containers/DevTools.js index 72a5c03..58de00f 100644 --- a/src/containers/DevTools.js +++ b/src/containers/DevTools.js @@ -14,8 +14,10 @@ const DevTools = createDevTools( * Consult their respective repos for further information. * Here, we are placing the LogMonitor within the DockMonitor. */ - + ); From 85cc402bc3467d0e9ad8b138e915556f3a6d547e Mon Sep 17 00:00:00 2001 From: Fredrik Lindell Date: Wed, 24 May 2017 22:25:29 +0200 Subject: [PATCH 7/9] Lint and migration work * Lint and migration work --- src/components/Counter.js | 35 ---------------------------- src/components/Footer.js | 13 ----------- src/containers/{App.js => App.jsx} | 4 ++-- src/containers/Root.dev.js | 27 ---------------------- src/containers/Root.js | 15 ------------ src/containers/Root.jsx | 37 ++++++++++++++++++++++++++++++ src/containers/Root.prod.js | 22 ------------------ src/index.js | 2 +- webpack.config.dev.js | 3 +++ 9 files changed, 43 insertions(+), 115 deletions(-) delete mode 100644 src/components/Counter.js delete mode 100644 src/components/Footer.js rename src/containers/{App.js => App.jsx} (96%) delete mode 100644 src/containers/Root.dev.js delete mode 100644 src/containers/Root.js create mode 100644 src/containers/Root.jsx delete mode 100644 src/containers/Root.prod.js diff --git a/src/components/Counter.js b/src/components/Counter.js deleted file mode 100644 index 53b87a6..0000000 --- a/src/components/Counter.js +++ /dev/null @@ -1,35 +0,0 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; - -export default class Counter extends Component { - - handleIncrement() { - this.props.actions.increment(); - } - - handleDecrement() { - this.props.actions.decrement(); - } - - render() { - return ( -
-
{this.props.counter}
- {/* Below, the even or odd statement is simply used to demonstrate how one could - easily use a ternary operator to conditionally show an 'even' or 'odd' string - based on the counter's value on state. */} -
{this.props.counter % 2 === 0 ? 'even' : 'odd'}
-
-
- - -
-
- ); - } -} - -Counter.propTypes = { - counter: PropTypes.number.isRequired, - actions: PropTypes.object.isRequired -}; diff --git a/src/components/Footer.js b/src/components/Footer.js deleted file mode 100644 index cfc37a2..0000000 --- a/src/components/Footer.js +++ /dev/null @@ -1,13 +0,0 @@ -import React, { Component } from 'react'; - -export default class Footer extends Component { - render() { - return ( - - ); - } -} diff --git a/src/containers/App.js b/src/containers/App.jsx similarity index 96% rename from src/containers/App.js rename to src/containers/App.jsx index 030092f..28863ad 100644 --- a/src/containers/App.js +++ b/src/containers/App.jsx @@ -3,8 +3,8 @@ import PropTypes from 'prop-types'; import { bindActionCreators } from 'redux'; import { connect } from 'react-redux'; import * as CounterActions from '../actions/CounterActions'; -import Counter from '../components/Counter'; -import Footer from '../components/Footer'; +import Counter from '../components/Counter.jsx'; +import Footer from '../components/Footer.jsx'; /** * It is common practice to have a 'Root' container/component require our main App (this one). diff --git a/src/containers/Root.dev.js b/src/containers/Root.dev.js deleted file mode 100644 index ed116fd..0000000 --- a/src/containers/Root.dev.js +++ /dev/null @@ -1,27 +0,0 @@ -import React, { Component } from 'react'; -import { Provider } from 'react-redux'; -import App from './App'; -import DevTools from './DevTools'; - -/** - * Component is exported for conditional usage in Root.js - */ -module.exports = class Root extends Component { - render() { - const { store } = this.props; - return ( - /** - * Provider is a component provided to us by the 'react-redux' bindings that - * wraps our app - thus making the Redux store/state available to our 'connect()' - * calls in component hierarchy below. - */ - -
- - {/* Being the dev version of our Root component, we include DevTools below */} - -
-
- ); - } -}; diff --git a/src/containers/Root.js b/src/containers/Root.js deleted file mode 100644 index 6c8be83..0000000 --- a/src/containers/Root.js +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Just like our store, we configure a 'Root' component that is - * required based on the env variable. This component is typically one - * surrounded by a . - */ - -let loadedModule = null; - -if (process.env.NODE_ENV === 'production') { - loadedModule = require('./Root.prod.js'); -} else { - loadedModule = require('./Root.dev.js'); -} - -export const Root = loadedModule; diff --git a/src/containers/Root.jsx b/src/containers/Root.jsx new file mode 100644 index 0000000..feddcc8 --- /dev/null +++ b/src/containers/Root.jsx @@ -0,0 +1,37 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { Provider } from 'react-redux'; +import App from './App'; +import DevTools from './DevTools'; + +/** + * Component is exported for conditional usage in Root.js + */ +const Root = (props) => { + const { store } = props; + const content = process.env.NODE_ENV === 'production' ? + : ( +
+ + {/* Being the dev version of our Root component, we include DevTools below */} + +
+ ); + + return ( + /** + * Provider is a component provided to us by the 'react-redux' bindings that + * wraps our app - thus making the Redux store/state available to our 'connect()' + * calls in component hierarchy below. + */ + + {content} + + ); +}; + +Root.propTypes = { + store: PropTypes.object.isRequired, +} + +export default Root; diff --git a/src/containers/Root.prod.js b/src/containers/Root.prod.js deleted file mode 100644 index a3c0bbe..0000000 --- a/src/containers/Root.prod.js +++ /dev/null @@ -1,22 +0,0 @@ -import React, { Component } from 'react'; -import { Provider } from 'react-redux'; -import App from './App'; - -/** - * Component is exported for conditional usage in Root.js - */ -module.exports = class Root extends Component { - render() { - const { store } = this.props; - return ( - /** - * Provider is a component provided to us by the 'react-redux' bindings that - * wraps our app - thus making the Redux store/state available to our 'connect()' - * calls in component hierarchy below. - */ - - - - ); - } -}; diff --git a/src/index.js b/src/index.js index cc9995c..5bda8f6 100644 --- a/src/index.js +++ b/src/index.js @@ -11,7 +11,7 @@ import './styles/main.scss'; * See configureStore.js and Root.js for more details. */ import { configureStore } from './store/configureStore'; -import { Root } from './containers/Root'; +import Root from './containers/Root.jsx'; const store = configureStore(); diff --git a/webpack.config.dev.js b/webpack.config.dev.js index 825a415..d60f990 100644 --- a/webpack.config.dev.js +++ b/webpack.config.dev.js @@ -14,6 +14,9 @@ module.exports = { filename: '[name]-[hash].js', publicPath: '/' }, + resolve: { + extensions: ['.js', '.jsx'] + }, plugins: [ /** * This is where the magic happens! You need this to enable Hot Module Replacement! From 529341bda448b9bd663b7e5cf6bc8c024ce17031 Mon Sep 17 00:00:00 2001 From: Fredrik Lindell Date: Wed, 24 May 2017 22:26:26 +0200 Subject: [PATCH 8/9] Adding Counter and Footer jsx * Adding Counter and Footer jsx --- src/components/Counter.jsx | 35 +++++++++++++++++++++++++++++++++++ src/components/Footer.jsx | 11 +++++++++++ 2 files changed, 46 insertions(+) create mode 100644 src/components/Counter.jsx create mode 100644 src/components/Footer.jsx diff --git a/src/components/Counter.jsx b/src/components/Counter.jsx new file mode 100644 index 0000000..53b87a6 --- /dev/null +++ b/src/components/Counter.jsx @@ -0,0 +1,35 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; + +export default class Counter extends Component { + + handleIncrement() { + this.props.actions.increment(); + } + + handleDecrement() { + this.props.actions.decrement(); + } + + render() { + return ( +
+
{this.props.counter}
+ {/* Below, the even or odd statement is simply used to demonstrate how one could + easily use a ternary operator to conditionally show an 'even' or 'odd' string + based on the counter's value on state. */} +
{this.props.counter % 2 === 0 ? 'even' : 'odd'}
+
+
+ + +
+
+ ); + } +} + +Counter.propTypes = { + counter: PropTypes.number.isRequired, + actions: PropTypes.object.isRequired +}; diff --git a/src/components/Footer.jsx b/src/components/Footer.jsx new file mode 100644 index 0000000..c2a3a0d --- /dev/null +++ b/src/components/Footer.jsx @@ -0,0 +1,11 @@ +import React, { Component } from 'react'; + +const Footer = () => ( + +) + +export default Footer; From 393e4dbc094e859bbe5a3006846c67d61f5130a0 Mon Sep 17 00:00:00 2001 From: Fredrik Lindell Date: Wed, 24 May 2017 23:26:03 +0200 Subject: [PATCH 9/9] All lint errors fixed * All lint errors fixed * removed react/forbid-prop-types since PropTypes.object was used in 3 places --- .eslintrc | 18 ++++++++- package.json | 2 +- src/components/Footer.jsx | 4 +- src/containers/App.jsx | 32 +++++++-------- src/containers/{DevTools.js => DevTools.jsx} | 0 src/containers/Root.jsx | 4 +- src/{index.js => index.jsx} | 5 ++- src/store/configureStore.dev.js | 33 --------------- src/store/configureStore.js | 42 ++++++++++++++++---- src/store/configureStore.prod.js | 11 ----- webpack.config.dev.js | 1 - webpack.config.prod.js | 5 ++- 12 files changed, 78 insertions(+), 79 deletions(-) rename src/containers/{DevTools.js => DevTools.jsx} (100%) rename src/{index.js => index.jsx} (80%) delete mode 100644 src/store/configureStore.dev.js delete mode 100644 src/store/configureStore.prod.js diff --git a/.eslintrc b/.eslintrc index 90132d2..3c62785 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,6 +1,20 @@ { "extends": "airbnb", + "parserOptions": { + "ecmaVersion": 6, + "sourceType": "module", + "ecmaFeatures": { + "forOf": true, + "jsx": true, + "es6": true, + "experimentalObjectRestSpread" : true + }, + }, "rules": { - "comma-dangle": 0 - } + "comma-dangle": 0, + "react/forbid-prop-types": [0] + }, + "plugins": [ + "react" + ] } diff --git a/package.json b/package.json index 4d38eda..cca82d5 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "build": "npm run clean && npm run build:webpack --progress --profile --colors", "dev": "NODE_ENV=development npm start", "start": "node devServer.js", - "lint": "eslint src" + "lint": "eslint --ext .js,.jsx src" }, "repository": { "type": "git", diff --git a/src/components/Footer.jsx b/src/components/Footer.jsx index c2a3a0d..6e6e082 100644 --- a/src/components/Footer.jsx +++ b/src/components/Footer.jsx @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React from 'react'; const Footer = () => (
@@ -6,6 +6,6 @@ const Footer = () => ( Made in SF with by David Tsai.
-) +); export default Footer; diff --git a/src/containers/App.jsx b/src/containers/App.jsx index 28863ad..c4101f8 100644 --- a/src/containers/App.jsx +++ b/src/containers/App.jsx @@ -1,30 +1,28 @@ -import React, { Component } from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; import { bindActionCreators } from 'redux'; import { connect } from 'react-redux'; import * as CounterActions from '../actions/CounterActions'; -import Counter from '../components/Counter.jsx'; -import Footer from '../components/Footer.jsx'; +import Counter from '../components/Counter'; +import Footer from '../components/Footer'; /** * It is common practice to have a 'Root' container/component require our main App (this one). * Again, this is because it serves to wrap the rest of our application with the Provider * component to make the Redux store available to the rest of the app. */ -class App extends Component { - render() { - // we can use ES6's object destructuring to effectively 'unpack' our props - const { counter, actions } = this.props; - return ( -
-
Simple Redux Boilerplate
- {/* notice that we then pass those unpacked props into the Counter component */} - -
-
- ); - } -} +const App = (props) => { + // we can use ES6's object destructuring to effectively 'unpack' our props + const { counter, actions } = props; + return ( +
+
Simple Redux Boilerplate
+ {/* notice that we then pass those unpacked props into the Counter component */} + +
+ ); +}; App.propTypes = { counter: PropTypes.number.isRequired, diff --git a/src/containers/DevTools.js b/src/containers/DevTools.jsx similarity index 100% rename from src/containers/DevTools.js rename to src/containers/DevTools.jsx diff --git a/src/containers/Root.jsx b/src/containers/Root.jsx index feddcc8..77c8a7c 100644 --- a/src/containers/Root.jsx +++ b/src/containers/Root.jsx @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; import { Provider } from 'react-redux'; import App from './App'; @@ -32,6 +32,6 @@ const Root = (props) => { Root.propTypes = { store: PropTypes.object.isRequired, -} +}; export default Root; diff --git a/src/index.js b/src/index.jsx similarity index 80% rename from src/index.js rename to src/index.jsx index 5bda8f6..07e8bb9 100644 --- a/src/index.js +++ b/src/index.jsx @@ -1,3 +1,4 @@ +/* global document */ import React from 'react'; import ReactDOM from 'react-dom'; /** @@ -10,8 +11,8 @@ import './styles/main.scss'; * Both configureStore and Root are required conditionally. * See configureStore.js and Root.js for more details. */ -import { configureStore } from './store/configureStore'; -import Root from './containers/Root.jsx'; +import configureStore from './store/configureStore'; +import Root from './containers/Root'; const store = configureStore(); diff --git a/src/store/configureStore.dev.js b/src/store/configureStore.dev.js deleted file mode 100644 index ef3bbc4..0000000 --- a/src/store/configureStore.dev.js +++ /dev/null @@ -1,33 +0,0 @@ -import { createStore, applyMiddleware, compose } from 'redux'; -import { createLogger } from 'redux-logger'; -import thunk from 'redux-thunk'; -import DevTools from '../containers/DevTools'; -import rootReducer from '../reducers'; - -/** - * Entirely optional, this tiny library adds some functionality to - * your DevTools, by logging actions/state to your console. Used in - * conjunction with your standard DevTools monitor gives you great - * flexibility! - */ -const logger = createLogger(); - -const finalCreateStore = compose( - // Middleware you want to use in development: - applyMiddleware(logger, thunk), - // Required! Enable Redux DevTools with the monitors you chose - DevTools.instrument() -)(createStore); - -module.exports = function configureStore(initialState) { - const store = finalCreateStore(rootReducer, initialState); - - // Hot reload reducers (requires Webpack or Browserify HMR to be enabled) - if (module.hot) { - module.hot.accept('../reducers', () => - store.replaceReducer(require('../reducers')) - ); - } - - return store; -}; diff --git a/src/store/configureStore.js b/src/store/configureStore.js index ccda34c..ea5c75a 100644 --- a/src/store/configureStore.js +++ b/src/store/configureStore.js @@ -1,15 +1,43 @@ +/* eslint-disable global-require */ /** * Based on the current environment variable, we need to make sure * to exclude any DevTools-related code from the production builds. * The code is envify'd - using 'DefinePlugin' in Webpack. */ -let loadedStore = null; +import { createStore, applyMiddleware, compose } from 'redux'; +import { createLogger } from 'redux-logger'; +import thunk from 'redux-thunk'; +import DevTools from '../containers/DevTools'; +import rootReducer from '../reducers'; -if (process.env.NODE_ENV === 'production') { - loadedStore = require('./configureStore.prod'); -} else { - loadedStore = require('./configureStore.dev'); -} +/** + * Entirely optional, this tiny library adds some functionality to + * your DevTools, by logging actions/state to your console. Used in + * conjunction with your standard DevTools monitor gives you great + * flexibility! + */ +const logger = createLogger(); + +const finalCreateStore = module.hot ? compose( + // Middleware you want to use in development: + applyMiddleware(logger, thunk), + // Required! Enable Redux DevTools with the monitors you chose + DevTools.instrument() +)(createStore) : compose( + applyMiddleware(thunk) +)(createStore); -export const configureStore = loadedStore; +export default function configureStore(initialState) { + const store = finalCreateStore(rootReducer, initialState); + + // Hot reload reducers (requires Webpack or Browserify HMR to be enabled) + if (module.hot) { + module.hot.accept('../reducers', () => + store.replaceReducer(require('../reducers')) + ); + } + + return store; +} +/* eslint-enable global-require */ diff --git a/src/store/configureStore.prod.js b/src/store/configureStore.prod.js deleted file mode 100644 index 5b3d6f8..0000000 --- a/src/store/configureStore.prod.js +++ /dev/null @@ -1,11 +0,0 @@ -import { createStore, applyMiddleware, compose } from 'redux'; -import thunk from 'redux-thunk'; -import rootReducer from '../reducers'; - -const finalCreateStore = compose( - applyMiddleware(thunk) -)(createStore); - -module.exports = function configureStore(initialState) { - return finalCreateStore(rootReducer, initialState); -}; diff --git a/webpack.config.dev.js b/webpack.config.dev.js index d60f990..977350c 100644 --- a/webpack.config.dev.js +++ b/webpack.config.dev.js @@ -28,7 +28,6 @@ module.exports = { * will not be emitted. If you want your webpack to 'fail', you need to check out * the bail option. */ -// new webpack.NoErrorsPlugin(), new webpack.NoEmitOnErrorsPlugin(), /** * This is a webpack plugin that simplifies creation of HTML files to serve your diff --git a/webpack.config.prod.js b/webpack.config.prod.js index 99e1976..6681d75 100644 --- a/webpack.config.prod.js +++ b/webpack.config.prod.js @@ -12,6 +12,9 @@ module.exports = { filename: '[name]-[hash].js', publicPath: './' }, + resolve: { + extensions: ['.js', '.jsx'] + }, plugins: [ /** * This plugin assigns the module and chunk ids by occurence count. What this @@ -50,7 +53,7 @@ module.exports = { module: { loaders: [ { - test: /\.js$/, + test: /\.js?/, loaders: ['babel-loader'], include: path.join(__dirname, 'src') },