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

Question: Enabling HRM Hot Module Replacement? #793

Open
edelgado opened this Issue Sep 27, 2017 · 10 comments

Comments

Projects
None yet
4 participants
@edelgado

edelgado commented Sep 27, 2017

Help us help you! Please choose one:

  • My app crashes with react-rails, so I've included the stack trace and the exact steps which make it crash.
  • My app doesn't crash, but I'm getting unexpected behavior. So, I've described the unexpected behavior and suggested a new behavior.
  • I'm trying to use react-rails with another library, but I'm having trouble. I've described my JavaScript management setup (eg, Sprockets, Webpack...), how I'm trying to use this other library, and why it's not working.
  • I have another issue to discuss.

Hi folks, I'm using Webpacker and react-rails and trying to get HRM Hot Module Replacement working on my project.

The webpack-dev-server.md doc in webpacker mentions that, in order to enable HMR for React we need add react-hot-loader as per these instructions.

I think I already did everything I need to do on the webpacker side of things: Step one, I did by adding the --hot option to the call of bin/webpack-dev-server in my Procfile. Additionally, I enabled the hmr setting in my webpacker.yml file.

I see in my console that HMR is enabled and it correctly listens to code changes. It's unable to hot-load modules tho, because the modules are not accepted:

image

The instructions for react-hot-loader says to modify your root container to accept HMR by changing the root React entry point from something like this:

import React from 'react';
import { render } from 'react-dom';
import RootContainer from './containers/rootContainer.js';

render(<RootContainer />, document.getElementById('react-root'));

To something like this:

 if (module.hot) {
   module.hot.accept('./containers/rootContainer.js', () => {
     const NextRootContainer = require('./containers/rootContainer.js').default;
     render(<NextRootContainer />, document.getElementById('react-root'));
   })
 }

But, how do I do that with react-rails? I use the react_component Rails view helper to integrate React components into Rails views.

I'm suspecting that HMR is not successful in my project because the React code is not setup to accept the hot modules. Where in my code can I add

Any help would be greatly appreciated!

@BookOfGreg

This comment has been minimized.

Show comment
Hide comment
@BookOfGreg

BookOfGreg Sep 28, 2017

Member

I actually spent a few hours looking into this myself last night, yep I could get HMR to initialize but I didn't make as much progress as you had done, I'll be honest I've never tried using the new HMR features of Webpacker 3 yet until you mentioned it so thanks for showing me something new and interesting 👍

Do you happen to know of any running example of HRM in the wild? Maybe a github example project of Webpacker + HMR working sould really help! That will make it infinitely easier for me to be building on a known good base than reinvent the wheel.

I'll make another attempt at getting a HMR component rendering in an example project when I have time.

Member

BookOfGreg commented Sep 28, 2017

I actually spent a few hours looking into this myself last night, yep I could get HMR to initialize but I didn't make as much progress as you had done, I'll be honest I've never tried using the new HMR features of Webpacker 3 yet until you mentioned it so thanks for showing me something new and interesting 👍

Do you happen to know of any running example of HRM in the wild? Maybe a github example project of Webpacker + HMR working sould really help! That will make it infinitely easier for me to be building on a known good base than reinvent the wheel.

I'll make another attempt at getting a HMR component rendering in an example project when I have time.

@edelgado

This comment has been minimized.

Show comment
Hide comment
@edelgado

edelgado Sep 29, 2017

Thanks for looking into it @BookOfGreg! Having HMR work with react-rails would be a huge time saver for developers as it would cut down on the amount of full-page refreshes we need to do when working on a component.

Here is an examples of HMR from from Dan himself: https://github.com/wkwiatek/react-hot-loader-minimal-boilerplate

More information can be found in http://gaearon.github.io/react-hot-loader/getstarted/

edelgado commented Sep 29, 2017

Thanks for looking into it @BookOfGreg! Having HMR work with react-rails would be a huge time saver for developers as it would cut down on the amount of full-page refreshes we need to do when working on a component.

Here is an examples of HMR from from Dan himself: https://github.com/wkwiatek/react-hot-loader-minimal-boilerplate

More information can be found in http://gaearon.github.io/react-hot-loader/getstarted/

@edelgado

This comment has been minimized.

Show comment
Hide comment
@edelgado

edelgado Sep 29, 2017

@BookOfGreg Also, this is a matching issue I created over at Webpacker, with some code hints from the authors there that may lead us in the right path: rails/webpacker#872

edelgado commented Sep 29, 2017

@BookOfGreg Also, this is a matching issue I created over at Webpacker, with some code hints from the authors there that may lead us in the right path: rails/webpacker#872

@BookOfGreg

This comment has been minimized.

Show comment
Hide comment
@BookOfGreg

BookOfGreg Oct 2, 2017

Member

Thanks for the investigation work so far! Yep I totally can't get it working without modifying something.
I've been getting an example app stood up at BookOfGreg/react-rails-example-app to tinker with this. Currently if I switch on HMR and touch a file, the serverside rendering errors with SyntaxError: Unexpected token const so looks like there is some interesting work to do in this area.

Summoning @RiccardoMargiotta

Member

BookOfGreg commented Oct 2, 2017

Thanks for the investigation work so far! Yep I totally can't get it working without modifying something.
I've been getting an example app stood up at BookOfGreg/react-rails-example-app to tinker with this. Currently if I switch on HMR and touch a file, the serverside rendering errors with SyntaxError: Unexpected token const so looks like there is some interesting work to do in this area.

Summoning @RiccardoMargiotta

@BookOfGreg BookOfGreg added this to the 2.5.0 milestone Nov 6, 2017

@BookOfGreg BookOfGreg self-assigned this Nov 6, 2017

@kkir

This comment has been minimized.

Show comment
Hide comment
@kkir

kkir Jan 11, 2018

Putting ReactRailsUJS.mountComponents() did the trick for me

if (module.hot) {
  module.hot.accept('../src/App', () => {
    ReactRailsUJS.mountComponents();
  });
}

kkir commented Jan 11, 2018

Putting ReactRailsUJS.mountComponents() did the trick for me

if (module.hot) {
  module.hot.accept('../src/App', () => {
    ReactRailsUJS.mountComponents();
  });
}
@BookOfGreg

This comment has been minimized.

Show comment
Hide comment
@BookOfGreg

BookOfGreg Jan 12, 2018

Member

@kkir That's good news! Could you share some example code, or PR onto https://github.com/bookofgreg/react-rails-example-app ? I've been unable to do it myself as of yet but I've never used HMR before either.

Member

BookOfGreg commented Jan 12, 2018

@kkir That's good news! Could you share some example code, or PR onto https://github.com/bookofgreg/react-rails-example-app ? I've been unable to do it myself as of yet but I've never used HMR before either.

@AirWick219

This comment has been minimized.

Show comment
Hide comment
@AirWick219

AirWick219 Mar 23, 2018

I am fighting with the HMR as well .. I was wondering where are we supposed to put the following code with respect too react-rails ?? is it in the javascript/packs/application.js where ReactRailsUJS.useContext ?? or the highest level components ?

if (module.hot) {
  module.hot.accept('../src/App', () => {
    ReactRailsUJS.mountComponents();
  });
}

AirWick219 commented Mar 23, 2018

I am fighting with the HMR as well .. I was wondering where are we supposed to put the following code with respect too react-rails ?? is it in the javascript/packs/application.js where ReactRailsUJS.useContext ?? or the highest level components ?

if (module.hot) {
  module.hot.accept('../src/App', () => {
    ReactRailsUJS.mountComponents();
  });
}
@BookOfGreg

This comment has been minimized.

Show comment
Hide comment
@BookOfGreg

BookOfGreg Mar 23, 2018

Member

I think it's meant to go in the packs but I've still not had time to work on this.

Member

BookOfGreg commented Mar 23, 2018

I think it's meant to go in the packs but I've still not had time to work on this.

@AirWick219

This comment has been minimized.

Show comment
Hide comment
@AirWick219

AirWick219 Mar 23, 2018

I tried something like this but webpack-dev-serverd doesn't seem to like this and throw a bunch of warning

javascript/packs/application.js

const componentRequireContext = require.context('../components', true);
const ReactRailsUJS = require('react_ujs');

ReactRailsUJS.useContext(componentRequireContext);

if (module.hot) {
  module.hot.accept('../components', () => {
    ReactRailsUJS.mountComponents();
  });
}

AirWick219 commented Mar 23, 2018

I tried something like this but webpack-dev-serverd doesn't seem to like this and throw a bunch of warning

javascript/packs/application.js

const componentRequireContext = require.context('../components', true);
const ReactRailsUJS = require('react_ujs');

ReactRailsUJS.useContext(componentRequireContext);

if (module.hot) {
  module.hot.accept('../components', () => {
    ReactRailsUJS.mountComponents();
  });
}
@AirWick219

This comment has been minimized.

Show comment
Hide comment
@AirWick219

AirWick219 Mar 24, 2018

I think I got it working without those code and just webpacker .. I do see module hot swapping without refreshing however, ran into an issue of module looking for a hot-update.json file with the content-type of text/html that's not there which caused a page reload.
See this for more details. rails/webpacker#1375

AirWick219 commented Mar 24, 2018

I think I got it working without those code and just webpacker .. I do see module hot swapping without refreshing however, ran into an issue of module looking for a hot-update.json file with the content-type of text/html that's not there which caused a page reload.
See this for more details. rails/webpacker#1375

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment