diff --git a/config-overrides.js b/config-overrides.js index 4bfb9d465f..4ec428f269 100644 --- a/config-overrides.js +++ b/config-overrides.js @@ -8,6 +8,7 @@ const debug = require('debug')('build:config-overrides'); const webpack = require('webpack'); const { injectBabelPlugin } = require('react-app-rewired'); const rewireStyledComponents = require('react-app-rewire-styled-components'); +const rewireReactHotLoader = require('react-app-rewire-hot-loader'); const swPrecachePlugin = require('sw-precache-webpack-plugin'); const fs = require('fs'); const path = require('path'); @@ -74,15 +75,19 @@ const transpileShared = config => { module.exports = function override(config, env) { if (process.env.NODE_ENV === 'development') { config.output.path = path.join(__dirname, './build'); + config = rewireReactHotLoader(config, env); + config.plugins.push( + WriteFilePlugin({ + log: true, + useHashIndex: false, + }) + ); } config.plugins.push( new ReactLoadablePlugin({ filename: './build/react-loadable.json', }) ); - if (process.env.NODE_ENV === 'production') { - removeEslint(config); - } config = injectBabelPlugin('react-loadable/babel', config); config = transpileShared(config); // Filter the default serviceworker plugin, add offline plugin instead @@ -126,14 +131,6 @@ module.exports = function override(config, env) { if (process.env.BUNDLE_BUDDY === 'true') { config.plugins.push(new BundleBuddyWebpackPlugin()); } - if (process.env.NODE_ENV === 'development') { - config.plugins.push( - WriteFilePlugin({ - log: true, - useHashIndex: false, - }) - ); - } config.plugins.unshift( new webpack.optimize.CommonsChunkPlugin({ names: ['bootstrap'], @@ -142,6 +139,7 @@ module.exports = function override(config, env) { }) ); if (process.env.NODE_ENV === 'production') { + removeEslint(config); config.plugins.push( new webpack.DefinePlugin({ 'process.env': { diff --git a/package.json b/package.json index effb6adf94..c8b36b416c 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,8 @@ "micromatch": "^3.0.4", "prettier": "^1.0.0", "raw-loader": "^0.5.1", + "react-app-rewire-hot-loader": "^1.0.1", + "react-hot-loader": "^4.3.1", "react-scripts": "^1.0.0", "rimraf": "^2.6.1", "sw-precache-webpack-plugin": "^0.11.4", diff --git a/src/index.js b/src/index.js index 5acbd36401..13c151d32d 100644 --- a/src/index.js +++ b/src/index.js @@ -11,6 +11,7 @@ import queryString from 'query-string'; import Loadable from 'react-loadable'; import * as OfflinePluginRuntime from 'offline-plugin/runtime'; import { HelmetProvider } from 'react-helmet-async'; +import { hot } from 'react-hot-loader'; import webPushManager from './helpers/web-push-manager'; import { history } from './helpers/history'; import { client } from 'shared/graphql'; @@ -61,13 +62,8 @@ if (t && (!existingUser || !existingUser.currentUser)) { const store = initStore(window.__SERVER_STATE__ || initialState); -const renderMethod = !!window.__SERVER_STATE__ - ? // $FlowIssue - ReactDOM.hydrate - : ReactDOM.render; - -function render() { - return renderMethod( +const App = hot(module)(() => { + return ( @@ -76,7 +72,18 @@ function render() { - , + + ); +}); + +const renderMethod = !!window.__SERVER_STATE__ + ? // $FlowIssue + ReactDOM.hydrate + : ReactDOM.render; + +function render() { + return renderMethod( + , // $FlowIssue document.querySelector('#root') ); diff --git a/yarn.lock b/yarn.lock index 4147c5e700..00f672008a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4529,7 +4529,7 @@ fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" -fast-levenshtein@~2.0.4: +fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.4: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" @@ -5029,7 +5029,7 @@ global-prefix@^1.0.1: is-windows "^1.0.1" which "^1.2.14" -global@^4.3.2: +global@^4.3.0, global@^4.3.2: version "4.3.2" resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" dependencies: @@ -8919,6 +8919,12 @@ react-apollo@2.x: lodash "4.17.5" prop-types "^15.6.0" +react-app-rewire-hot-loader@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/react-app-rewire-hot-loader/-/react-app-rewire-hot-loader-1.0.1.tgz#511f06d85e1c05d3ea1c3cdaede352e1871183ba" + dependencies: + webpack "^3.6.0" + react-app-rewire-styled-components@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/react-app-rewire-styled-components/-/react-app-rewire-styled-components-3.0.2.tgz#e1acfaff2738af7ff4c4ad557ebd4599d6cda862" @@ -9002,12 +9008,27 @@ react-helmet-async@^0.1.0: prop-types "^15.6.1" shallowequal "^1.0.2" +react-hot-loader@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/react-hot-loader/-/react-hot-loader-4.3.1.tgz#47f59fe09b97ec655e77a1f90819785eda513a86" + dependencies: + fast-levenshtein "^2.0.6" + global "^4.3.0" + hoist-non-react-statics "^2.5.0" + prop-types "^15.6.1" + react-lifecycles-compat "^3.0.4" + shallowequal "^1.0.2" + react-infinite-scroller-with-scroll-element@2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/react-infinite-scroller-with-scroll-element/-/react-infinite-scroller-with-scroll-element-2.0.2.tgz#1a59ee022cd798260593c1322794ed809cd5e2a5" dependencies: prop-types "^15.5.8" +react-lifecycles-compat@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" + react-loadable@^5.4.0: version "5.4.0" resolved "https://registry.yarnpkg.com/react-loadable/-/react-loadable-5.4.0.tgz#3b6b7d51121a7868fd155be848a36e02084742c9" @@ -11388,6 +11409,33 @@ webpack@^3.0.0: webpack-sources "^1.0.1" yargs "^8.0.2" +webpack@^3.6.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.12.0.tgz#3f9e34360370602fcf639e97939db486f4ec0d74" + dependencies: + acorn "^5.0.0" + acorn-dynamic-import "^2.0.0" + ajv "^6.1.0" + ajv-keywords "^3.1.0" + async "^2.1.2" + enhanced-resolve "^3.4.0" + escope "^3.6.0" + interpret "^1.0.0" + json-loader "^0.5.4" + json5 "^0.5.1" + loader-runner "^2.3.0" + loader-utils "^1.1.0" + memory-fs "~0.4.1" + mkdirp "~0.5.0" + node-libs-browser "^2.0.0" + source-map "^0.5.3" + supports-color "^4.2.1" + tapable "^0.2.7" + uglifyjs-webpack-plugin "^0.4.6" + watchpack "^1.4.0" + webpack-sources "^1.0.1" + yargs "^8.0.2" + websocket-driver@>=0.5.1: version "0.7.0" resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.0.tgz#0caf9d2d755d93aee049d4bdd0d3fe2cca2a24eb"