diff --git a/.babelrc b/.babelrc index f040c5e..cd1736b 100644 --- a/.babelrc +++ b/.babelrc @@ -6,7 +6,8 @@ ], "plugins": [ "transform-decorators-legacy", - "transform-object-rest-spread" + "transform-object-rest-spread", + "react-hot-loader/babel" ], "env": { "test": { diff --git a/conf/webpack/Base.js b/conf/webpack/Base.js index 42a266c..7969be9 100644 --- a/conf/webpack/Base.js +++ b/conf/webpack/Base.js @@ -69,9 +69,14 @@ class WebpackBaseConfig { * @return {Object} */ get defaultSettings() { + const cssModulesQuery = { + modules: true, + importLoaders: 1, + localIdentName: '[name]-[local]-[hash:base64:5]' + }; + return { context: this.srcPathAbsolute, - debug: false, devtool: 'eval', devServer: { contentBase: './src/', @@ -81,93 +86,110 @@ class WebpackBaseConfig { inline: true, port: 8000 }, - entry: './client.js', + entry: './index.js', module: { - preLoaders: [ + rules: [ { - test: /\.(js|jsx)$/, + enforce: 'pre', + test: /\.js?$/, include: this.srcPathAbsolute, - loader: 'eslint' - } - ], - loaders: [ - { - test: /\.cssmodule\.css$/, - loaders: [ - 'style', - 'css?modules&importLoaders=1&localIdentName=[name]-[local]-[hash:base64:5]' - ] + loader: 'babel-loader', + query: { + presets: ['es2015'] + } }, { test: /^.((?!cssmodule).)*\.css$/, loaders: [ - 'style', - 'css' + { loader: 'style-loader' }, + { loader: 'css-loader' } ] }, { - test: /\.cssmodule\.(sass|scss)$/, - loaders: [ - 'style', - 'css?modules&importLoaders=1&localIdentName=[name]-[local]-[hash:base64:5]', - 'sass' - ] + test: /\.(png|jpg|gif|mp4|ogg|svg|woff|woff2)$/, + loader: 'file-loader' }, { test: /^.((?!cssmodule).)*\.(sass|scss)$/, loaders: [ - 'style', - 'css', - 'sass' + { loader: 'style-loader' }, + { loader: 'css-loader' }, + { loader: 'sass-loader' } ] }, { - test: /\.cssmodule\.less$/, + test: /^.((?!cssmodule).)*\.less$/, loaders: [ - 'style', - 'css?modules&importLoaders=1&localIdentName=[name]-[local]-[hash:base64:5]', - 'less' + { loader: 'style-loader' }, + { loader: 'css-loader' }, + { loader: 'less-loader' } ] }, { - test: /^.((?!cssmodule).)*\.less$/, + test: /^.((?!cssmodule).)*\.styl$/, loaders: [ - 'style', - 'css', - 'less' + { loader: 'style-loader' }, + { loader: 'css-loader' }, + { loader: 'stylus-loader' } ] }, { - test: /\.cssmodule\.styl$/, + test: /\.json$/, + loader: 'json-loader' + }, + { + test: /\.(js|jsx)$/, + include: [].concat( + this.includedPackages, + [this.srcPathAbsolute] + ), loaders: [ - 'style', - 'css?modules&importLoaders=1&localIdentName=[name]-[local]-[hash:base64:5]', - 'stylus' + // Note: Moved this to .babelrc + { loader: 'babel-loader' } ] }, { - test: /^.((?!cssmodule).)*\.styl$/, + test: /\.cssmodule\.(sass|scss)$/, loaders: [ - 'style', - 'css', - 'stylus' + { loader: 'style-loader'}, + { + loader: 'css-loader', + query: cssModulesQuery + }, + { loader: 'sass-loader' } ] }, { - test: /\.(png|jpg|gif|mp4|ogg|svg|woff|woff2)$/, - loaders: ['file'] + test: /\.cssmodule\.css$/, + loaders: [ + { loader: 'style-loader'}, + { + loader: 'css-loader', + query: cssModulesQuery + } + ] }, { - test: /\.json$/, - loaders: 'json' + test: /\.cssmodule\.less$/, + loaders: [ + { loader: 'style-loader'}, + { + loader: 'css-loader', + query: cssModulesQuery + }, + { loader: 'less-loader' } + ] }, { - test: /\.(js|jsx)$/, - include: [].concat( - this.includedPackages, - [this.srcPathAbsolute] - ), - loaders: ['react-hot', 'babel'] + test: /\.cssmodule\.styl$/, + loaders: [ + { loader: 'style-loader'}, + { + loader: 'css-loader', + query: cssModulesQuery + }, + { loader: 'stylus-loader' } + ] } ] }, @@ -187,7 +209,7 @@ class WebpackBaseConfig { stores: `${this.srcPathAbsolute}/stores/`, styles: `${this.srcPathAbsolute}/styles/` }, - extensions: ['', '.js', '.jsx'], + extensions: ['.js', '.jsx'], modules: [ this.srcPathAbsolute, 'node_modules' diff --git a/conf/webpack/Dev.js b/conf/webpack/Dev.js index ff5f31f..2addb24 100644 --- a/conf/webpack/Dev.js +++ b/conf/webpack/Dev.js @@ -15,6 +15,7 @@ class WebpackDevConfig extends WebpackBaseConfig { entry: [ 'webpack-dev-server/client?http://0.0.0.0:8000/', 'webpack/hot/only-dev-server', + 'react-hot-loader/patch', './client.js' ], plugins: [ diff --git a/conf/webpack/Dist.js b/conf/webpack/Dist.js index 11cf764..891eff9 100644 --- a/conf/webpack/Dist.js +++ b/conf/webpack/Dist.js @@ -14,11 +14,13 @@ class WebpackDistConfig extends WebpackBaseConfig { this.config = { cache: false, devtool: 'source-map', + entry: [ + './client.js' + ], plugins: [ new webpack.DefinePlugin({ 'process.env.NODE_ENV': '"production"' }), - new webpack.optimize.DedupePlugin(), new webpack.optimize.AggressiveMergingPlugin(), new webpack.NoErrorsPlugin() ] diff --git a/conf/webpack/Test.js b/conf/webpack/Test.js index 24d4af8..a958c2c 100644 --- a/conf/webpack/Test.js +++ b/conf/webpack/Test.js @@ -12,19 +12,29 @@ class WebpackTestConfig extends WebpackBaseConfig { super(); this.config = { devtool: 'inline-source-map', + entry: [ + './client.js' + ], externals: { - cheerio: 'window', - 'react/lib/ExecutionEnvironment': true, - 'react/addons': true, - 'react/lib/ReactContext': true, + 'cheerio': 'window', + 'react/addons': 'true', + 'react/lib/ExecutionEnvironment': 'true', + 'react/lib/ReactContext': 'true' }, module: { loaders: [ { test: /\.cssmodule\.css$/, loaders: [ - 'style', - 'css?modules&importLoaders=1&localIdentName=[name]-[local]-[hash:base64:5]' + { loader: 'style-loader'}, + { + loader: 'css-loader', + query: { + modules: true, + importLoaders: 1, + localIdentName: '[name]-[local]-[hash:base64:5]' + } + } ] }, { @@ -37,7 +47,7 @@ class WebpackTestConfig extends WebpackBaseConfig { }, { test: /\.json$/, - loader: 'json' + loader: 'json-loader' }, { test: /\.(js|jsx)$/, diff --git a/package.json b/package.json index 14f7b7c..42b22ed 100644 --- a/package.json +++ b/package.json @@ -39,9 +39,9 @@ "homepage": "https://github.com/react-webpack-generators/react-webpack-template#readme", "devDependencies": { "babel-core": "^6.7.6", - "babel-eslint": "^6.0.4", + "babel-eslint": "^7.1.0", "babel-loader": "^6.2.4", - "babel-plugin-istanbul": "^2.0.0", + "babel-plugin-istanbul": "^3.0.0", "babel-plugin-transform-decorators-legacy": "^1.3.4", "babel-plugin-transform-object-rest-spread": "^6.8.0", "babel-polyfill": "^6.9.0", @@ -50,13 +50,13 @@ "babel-preset-react": "^6.5.0", "chai": "^3.5.0", "copyfiles": "^1.0.0", - "css-loader": "^0.24.0", + "css-loader": "^0.26.0", "enzyme": "^2.2.0", "eslint": "^3.0.0", - "eslint-config-airbnb": "^10.0.0", + "eslint-config-airbnb": "^13.0.0", "eslint-loader": "^1.3.0", - "eslint-plugin-import": "^1.4.0", - "eslint-plugin-jsx-a11y": "^2.0.0", + "eslint-plugin-import": "^2.2.0", + "eslint-plugin-jsx-a11y": "^2.2.0", "eslint-plugin-react": "^6.0.0", "file-loader": "^0.9.0", "karma": "^1.0.0", @@ -73,18 +73,18 @@ "null-loader": "^0.1.1", "phantomjs-prebuilt": "^2.1.7", "react-addons-test-utils": "^15.0.1", - "react-hot-loader": "^1.3.0", "rimraf": "^2.5.2", "sinon": "^1.17.3", "style-loader": "^0.13.1", "url-loader": "^0.5.7", "webpack": "^2.1.0-beta.6", - "webpack-dev-server": "^2.0.0-beta" + "webpack-dev-server": "^2.1.0-beta" }, "dependencies": { - "cross-env": "^2.0.0", + "cross-env": "^3.1.0", "react": "^15.0.1", - "react-dom": "^15.0.1" + "react-dom": "^15.0.1", + "react-hot-loader": "^3.0.0-beta.6" }, "engines": { "node": ">= 4.0.0", diff --git a/src/client.js b/src/client.js index e2d1cba..61e28d3 100644 --- a/src/client.js +++ b/src/client.js @@ -1,5 +1,23 @@ import React from 'react'; import ReactDOM from 'react-dom'; +import { AppContainer } from 'react-hot-loader'; import App from './components/App'; -ReactDOM.render(, document.getElementById('app')); +ReactDOM.render( + + + , + document.getElementById('app') +); + +if (module.hot) { + module.hot.accept('./components/App', () => { + const NextApp = require('./components/App').default; // eslint-disable-line global-require + ReactDOM.render( + + + , + document.getElementById('app') + ); + }); +}