Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Full reloads with react-hot-loader/webpack #642

Closed
KidkArolis opened this issue Sep 24, 2017 · 7 comments
Closed

Full reloads with react-hot-loader/webpack #642

KidkArolis opened this issue Sep 24, 2017 · 7 comments

Comments

@KidkArolis
Copy link
Contributor

Description

I tried using react-hot-loader/webpack as described in the docs, because I'm not using babel in my setup. However, this way the hot reloading doesn't work, it reloads the top level container losing the state of all nested components.

Expected behavior

It should work the same as in react-hot-loader/babel mode - components are swapped without losing state.

Actual behavior

All state of all the components is lost upon reloading.

Environment

React Hot Loader version: 3.0.0-beta7

Reproducible Demo

To reproduce:

git clone [email protected]:KidkArolis/react-hot-boilerplate.git
git checkout webpack-loader-issue
npm install
npm start
open http://localhost:3000
vim src/Counter.js # and save, the counter resets, but it shouldn't

This is all I changed in the default react-hot-boilerplate:
KidkArolis/react-hot-boilerplate@c72df24
image

@KidkArolis
Copy link
Contributor Author

I have diffed the bundle.js produced in both modes and here is a comparison of individual module:

react-hot-loader/babel

{
  /***/
  "./src/Layout.js":
  /***/
    (function(module, __webpack_exports__, __webpack_require__) {

    "use strict";
    /* harmony export (immutable) */
    __webpack_exports__["a"] = Layout;
    /* harmony import */
    var __WEBPACK_IMPORTED_MODULE_0_react__ = __webpack_require__("./node_modules/react/react.js");
    /* harmony import */
    var __WEBPACK_IMPORTED_MODULE_0_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_react__);


    function Layout(_ref) {
      var children = _ref.children;

      return __WEBPACK_IMPORTED_MODULE_0_react___default.a.createElement(
        'div',
        null,
        __WEBPACK_IMPORTED_MODULE_0_react___default.a.createElement(
          'h1',
          null,
          'Hello, world!'
        ),
        children
      );
    };

    var _temp = function() {
      if (typeof __REACT_HOT_LOADER__ === 'undefined') {
        return;
      }

      __REACT_HOT_LOADER__.register(Layout, 'Layout', '/Users/karolis/Desktop/react-hot-boilerplate/src/Layout.js');
    }();

    ;

    /***/
  })
}

react-hot-loader/webpack

{
  /***/
  "./src/Layout.js":
  /***/
    (function(module, __webpack_exports__, __webpack_require__) {

    "use strict";
    /* WEBPACK VAR INJECTION */
    (function(process, module) { /* harmony export (immutable) */
      __webpack_exports__["a"] = Layout;
      /* harmony import */
      var __WEBPACK_IMPORTED_MODULE_0_react__ = __webpack_require__("./node_modules/react/react.js");
      /* harmony import */
      var __WEBPACK_IMPORTED_MODULE_0_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_react__);


      function Layout(_ref) {
        var children = _ref.children;

        return __WEBPACK_IMPORTED_MODULE_0_react___default.a.createElement(
          'div',
          null,
          __WEBPACK_IMPORTED_MODULE_0_react___default.a.createElement(
            'h1',
            null,
            'Hello, world!'
          ),
          children
        );
      }

      ;
      (function register() { /* react-hot-loader/webpack */
        if (process.env.NODE_ENV !== 'production') {
          if (typeof __REACT_HOT_LOADER__ === 'undefined') {
            return;
          }
          if (typeof module.exports === 'function') {
            __REACT_HOT_LOADER__.register(module.exports, 'module.exports', "/Users/karolis/Desktop/react-hot-boilerplate/src/Layout.js");
            return;
          }
          for (var key in module.exports) {
            if (!Object.prototype.hasOwnProperty.call(module.exports, key)) {
              continue;
            }
            var namedExport = void 0;
            try {
              namedExport = module.exports[key];
            } catch (err) {
              continue;
            }
            __REACT_HOT_LOADER__.register(namedExport, key, "/Users/karolis/Desktop/react-hot-boilerplate/src/Layout.js");
          }
        }
      })();
      /* WEBPACK VAR INJECTION */
    }.call(__webpack_exports__, __webpack_require__("./node_modules/node-libs-browser/node_modules/process/browser.js"), __webpack_require__("./node_modules/webpack/buildin/harmony-module.js")(module)))

    /***/
  })
}

@mqklin
Copy link

mqklin commented Sep 28, 2017

Same issue, this is blocking me from using RHL v3

@gregberge
Copy link
Collaborator

I think there is a lot of bug using Webpack without Babel. I need to check but if you want to be safe use Babel.

@theKashey
Copy link
Collaborator

@KidkArolis - webpack plugin will "see" only exports. Babel will "see" all top level variables.
You should always use Babel plugin, not webpack one.

PS: And RHL had nothing with "full page reloads". Please - just check console output.
Webpack's HRM(HMR!=RHL) will allways describe why page in going to reload.

@KidkArolis
Copy link
Contributor Author

@theKashey - did you try to reproduce the issue with my example? The feature is not working as advertised..

@theKashey
Copy link
Collaborator

@KidkArolis - yep. Actually, I did the same in the beginning and nothing works.
Loosing internal state occurs when react-proxy could not replace old Component by a new one. And it occurs then old(or new) Components in not registered.
So - to get it working you have to:

  1. export ALL used components(ALL!). Cos webpack plugin works on module exports.
  2. use babel plugin. It could be the only babel thing inside your code, you can just disable(not use) rest of Babel's magic.

Even in this case, RHL will break on HoC composition( and decorators) and so on.

__REACT_HOT_LOADER__.register must be invoked for all the spare parts and Component. Sometimes it is not quite easy. Especially with the webpack plugin :(

@gregberge
Copy link
Collaborator

About this issue, this is probably due to Webpack since you see a full reload. Also, Webpack plugin support is very limited (only module exports).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants