diff --git a/examples/styled-components/src/App.js b/examples/styled-components/src/App.js
index 0c28c5ee1..d76d87737 100644
--- a/examples/styled-components/src/App.js
+++ b/examples/styled-components/src/App.js
@@ -25,7 +25,7 @@ const indirect = {
const indirectStyled = {
DS: styled.div`
- border: px solid #f00;
+ border: 2px solid #f00;
`,
DE: emoStyled('div')`border: 1px solid #F00`,
};
@@ -39,10 +39,17 @@ const OtherComponent = () => test;
const Context = React.createContext();
const Hook = () => {
- const [state] = React.useState({ x: 4 });
+ const [state, setState] = React.useState({ x: 2 });
+ React.useEffect(
+ () =>
+ setState(state => ({
+ x: state.x + 1,
+ })),
+ [],
+ );
return (
- hook state: {state.x}
+ hook state 1: {state.x}
);
@@ -128,6 +135,7 @@ const App = () => ;
setConfig({
logLevel: 'debug',
+ hotHooks: true,
});
// return App;
diff --git a/examples/styled-components/webpack.config.babel.js b/examples/styled-components/webpack.config.babel.js
index b66bdf995..86f5ba2b1 100644
--- a/examples/styled-components/webpack.config.babel.js
+++ b/examples/styled-components/webpack.config.babel.js
@@ -6,7 +6,7 @@ const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: ['./src/index'],
mode: process.env.NODE_ENV || 'development',
- devtool: 'eval-source-map',
+ devtool: false,
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
diff --git a/index.js b/index.js
index 2ac074c13..98dde5a8a 100644
--- a/index.js
+++ b/index.js
@@ -8,8 +8,9 @@ if (process.env.NODE_ENV === 'production') {
// this is just server environment
module.exports = require('./dist/react-hot-loader.production.min.js');
} else if (!module.hot) {
- console.error('React-Hot-Loader: Hot Module Replacement is not enabled');
module.exports = require('./dist/react-hot-loader.production.min.js');
+ module.exports.AppContainer.warnAboutHMRDisabled = true;
+ module.exports.hot.shouldWrapWithAppContainer = true;
} else {
var evalAllowed = false;
try {
diff --git a/root.js b/root.js
index 6f4cec538..65b702932 100644
--- a/root.js
+++ b/root.js
@@ -1,28 +1,30 @@
-if (module.hot) {
+if (process.env.NODE_ENV !== 'production') {
var hot = require('./index').hot;
- var cache = require.cache;
+ if (module.hot) {
+ var cache = require.cache;
- if (!module.parents || module.parents.length === 0) {
- throw new Error(
- 'React-Hot-Loader: `react-hot-loader/root` is not supported on your system. ' +
+ if (!module.parents || module.parents.length === 0) {
+ throw new Error(
+ 'React-Hot-Loader: `react-hot-loader/root` is not supported on your system. ' +
'Please use `import {hot} from "react-hot-loader"` instead'
- );
- }
- // access parent
- var parent = cache[module.parents[0]];
- if (!parent) {
- throw new Error(
- 'React-Hot-Loader: `react-hot-loader/root` is not supported on your system. ' +
+ );
+ }
+ // access parent
+ var parent = cache[module.parents[0]];
+ if (!parent) {
+ throw new Error(
+ 'React-Hot-Loader: `react-hot-loader/root` is not supported on your system. ' +
'Please use `import {hot} from "react-hot-loader"` instead'
- );
+ );
+ }
+ // remove self from a cache
+ delete cache[module.id];
}
- // remove self from a cache
- delete cache[module.id];
// setup hot for caller
exports.hot = hot(parent);
} else {
// prod mode
- exports.hot = function(a) {
+ exports.hot = function (a) {
return a;
};
}
diff --git a/src/AppContainer.prod.js b/src/AppContainer.prod.js
index 1bb8acc91..c797f616d 100644
--- a/src/AppContainer.prod.js
+++ b/src/AppContainer.prod.js
@@ -3,7 +3,16 @@
import React from 'react';
function AppContainer(props) {
+ if (AppContainer.warnAboutHMRDisabled) {
+ AppContainer.warnAboutHMRDisabled = true;
+ console.error(
+ 'React-Hot-Loader: misconfiguration detected, using production version in not production environment.',
+ );
+ console.error('React-Hot-Loader: Hot Module Replacement is not enabled.');
+ }
return React.Children.only(props.children);
}
+AppContainer.warnAboutHMRDisabled = false;
+
export default AppContainer;
diff --git a/src/babel.prod.js b/src/babel.prod.js
index 42681f209..5b6166fb2 100644
--- a/src/babel.prod.js
+++ b/src/babel.prod.js
@@ -1,4 +1,6 @@
const RHLPackage = 'react-hot-loader';
+const RHLRootPackage = 'react-hot-loader/root';
+const RHLPackages = [RHLPackage, RHLRootPackage];
function isImportedFromRHL(path, name) {
const binding = path.scope.getBinding(name);
@@ -6,7 +8,7 @@ function isImportedFromRHL(path, name) {
if (bindingType === 'ImportSpecifier' || bindingType === 'ImportNamespaceSpecifier') {
const bindingParent = binding.path.parent;
- return bindingParent.source.value === RHLPackage;
+ return RHLPackages.includes(bindingParent.source.value);
}
return false;
@@ -20,7 +22,7 @@ function getRHLContext(file) {
const bodyItem = body[i];
const { source, specifiers } = bodyItem;
- if (bodyItem.type !== 'ImportDeclaration' || source.value !== RHLPackage) {
+ if (bodyItem.type !== 'ImportDeclaration' || !RHLPackages.includes(source.value)) {
continue;
}
@@ -58,6 +60,7 @@ export default function plugin() {
const specifier = this.rhlContext[i];
if (specifier.kind === 'named') {
+ // replaces hot(module)(App)
if (
path.node.callee.name === specifier.local &&
// ensure that this is `hot` from RHL
@@ -69,7 +72,21 @@ export default function plugin() {
path.parentPath.replaceWith(path.parent.arguments[0]);
break;
}
+
+ // replaces hot(App)
+ if (
+ path.node.callee.name === specifier.local &&
+ // ensure that this is `hot` from RHL
+ isImportedFromRHL(path, specifier.local) &&
+ path.type === 'CallExpression' &&
+ path.node.arguments[0] &&
+ path.node.arguments[0].type === 'Identifier'
+ ) {
+ path.replaceWith(path.node.arguments[0]);
+ break;
+ }
} else if (specifier.kind === 'namespace') {
+ // replaces RHL.hot(module)(App)
if (
path.node.callee.callee &&
path.node.callee.callee.type === 'MemberExpression' &&
diff --git a/src/hot.prod.js b/src/hot.prod.js
index 7f8a68356..fd1e64c48 100644
--- a/src/hot.prod.js
+++ b/src/hot.prod.js
@@ -1 +1,17 @@
-export default () => Component => Component;
+import React from 'react';
+import AppContainer from './AppContainer.prod';
+
+const hot = () => {
+ if (hot.shouldWrapWithAppContainer) {
+ return Component => props => (
+
+
+
+ );
+ }
+ return Component => Component;
+};
+
+hot.shouldWrapWithAppContainer = false;
+
+export default hot;
diff --git a/test/__babel_fixtures__/drop-hot.prod.js b/test/__babel_fixtures__/drop-hot.prod.js
index 13a729add..486487916 100644
--- a/test/__babel_fixtures__/drop-hot.prod.js
+++ b/test/__babel_fixtures__/drop-hot.prod.js
@@ -1,6 +1,7 @@
import React from 'react'
import { hot, foo } from 'react-hot-loader'
import { hot as namedHot, foo as namedFoo } from 'react-hot-loader'
+import { hot as rootHot } from 'react-hot-loader/root'
import { hot as namedHot2 } from 'react-hot-loader'
import { hot as notRHLHot } from 'not-react-hot-loader'
import * as RHL from 'react-hot-loader'
@@ -10,6 +11,7 @@ import * as NOTRHL from 'not-react-hot-loader'
const App = () => Hello World!
const a = hot(module)(App);
+const z = rootHot(App);
const b = namedHot(module)(App);
const c = namedHot2(module)(App);
const d = RHL.hot(module)(App);
@@ -21,4 +23,4 @@ namedFoo(module)(App);
RHL.foo(module)(App);
NOTRHL.hot(module)(App);
-export { a, b, c, d, e };
+export { a, b, c, d, e, z };
diff --git a/test/__snapshots__/babel.test.js.snap b/test/__snapshots__/babel.test.js.snap
index b46f621d6..05f476cb2 100644
--- a/test/__snapshots__/babel.test.js.snap
+++ b/test/__snapshots__/babel.test.js.snap
@@ -1007,7 +1007,7 @@ exports[`babel Targetting "es2015" tags potential React components drop hot.prod
Object.defineProperty(exports, \\"__esModule\\", {
value: true
});
-exports.e = exports.d = exports.c = exports.b = exports.a = undefined;
+exports.z = exports.e = exports.d = exports.c = exports.b = exports.a = undefined;
var _react = require('react');
@@ -1019,6 +1019,8 @@ var RHL = _interopRequireWildcard(_reactHotLoader);
var RHL2 = _interopRequireWildcard(_reactHotLoader);
+var _root = require('react-hot-loader/root');
+
var _notReactHotLoader = require('not-react-hot-loader');
var NOTRHL = _interopRequireWildcard(_notReactHotLoader);
@@ -1036,6 +1038,7 @@ var App = function App() {
};
var a = App;
+var z = App;
var b = App;
var c = App;
var d = App;
@@ -1051,7 +1054,8 @@ exports.a = a;
exports.b = b;
exports.c = c;
exports.d = d;
-exports.e = e;"
+exports.e = e;
+exports.z = z;"
`;
exports[`babel Targetting "es2015" tags potential React components issue 246.js 1`] = `
@@ -1883,7 +1887,7 @@ exports[`babel Targetting "modern" tags potential React components drop hot.prod
Object.defineProperty(exports, \\"__esModule\\", {
value: true
});
-exports.e = exports.d = exports.c = exports.b = exports.a = undefined;
+exports.z = exports.e = exports.d = exports.c = exports.b = exports.a = undefined;
var _react = require('react');
@@ -1895,6 +1899,8 @@ var RHL = _interopRequireWildcard(_reactHotLoader);
var RHL2 = _interopRequireWildcard(_reactHotLoader);
+var _root = require('react-hot-loader/root');
+
var _notReactHotLoader = require('not-react-hot-loader');
var NOTRHL = _interopRequireWildcard(_notReactHotLoader);
@@ -1910,6 +1916,7 @@ const App = () => _react2.default.createElement(
);
const a = App;
+const z = App;
const b = App;
const c = App;
const d = App;
@@ -1925,7 +1932,8 @@ exports.a = a;
exports.b = b;
exports.c = c;
exports.d = d;
-exports.e = e;"
+exports.e = e;
+exports.z = z;"
`;
exports[`babel Targetting "modern" tags potential React components issue 246.js 1`] = `