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

React module is not hot updated after my upgrade of webpack to v2 and webpack-dev-server to v2 #469

Closed
vivaxy opened this issue Jan 31, 2017 · 23 comments

Comments

@vivaxy
Copy link

vivaxy commented Jan 31, 2017

If you are reporting a bug or having an issue setting up React Hot Loader, please fill in below. For feature requests, feel free to remove this template entirely.

Description

React module is not updated, after I edited ./src/components/DemoButton.js, changed something.

Expected behavior

Modules updated.

Actual behavior

image

Update traces are correct.

image

Breakpoints in render method was called. But nothing happened in DOM tree.

Environment

React Hot Loader version: 3.0.0-beta.6

Run these commands in the project folder and fill in their results:

  1. node -v: v6.6.0
  2. npm -v: 3.10.3

Then, specify:

  1. Operating system: macOS
  2. Browser and version: Chrome 55.0.2883.95 (64-bit)

Reproducible Demo

https://github.com/vivaxy/gt-react-scaffold/tree/db4a02582452772ac4533b3b0f199e831f339578

@vivaxy
Copy link
Author

vivaxy commented Jan 31, 2017

It worked fine after I removed react-router.

@nikolaipaul
Copy link

@vivaxy what are you using instead of react-router? I'm hitting the same problem.

@vivaxy
Copy link
Author

vivaxy commented Feb 8, 2017

@nikolaipaul It's not fixed. I removed react-router just to find out what part causes this problem.
It seems this bug is regarding to react-router hot reload support. I have added hack code to accept router hot reload. But this doesn't work after my upgrade to webpack@2.x.

@bjudson
Copy link

bjudson commented Feb 8, 2017

Having the same problem with React Router v3.0.2 (Webpack 2.2.1, react hot loader 3.0.0-beta.6). I also see the warning:

Warning: [react-router] You cannot change <Router routes>; it will be ignored

@bjudson
Copy link

bjudson commented Feb 9, 2017

@vivaxy @nikolaipaul this fixed my issue, have you tried it? #240 (comment)

i currently have:

renderApp(Root)

if (module.hot) {
    module.hot.accept(() => {
        renderApp(Root)
    })
}

rather than module.hot.accept('./containers/root', () => {

@vivaxy
Copy link
Author

vivaxy commented Feb 10, 2017

@bjudson I tried, It's still not working. I've noticed that repo does not use react-router.
And if you want to fix react-router warning, you might have to try this.

@bjudson
Copy link

bjudson commented Feb 10, 2017

Not too concerned about the warning, as long as it works :)

I am using react-router, and above fix worked for me. Not really sure react-router was my problem though.

@wkwiatek
Copy link
Collaborator

I think problem is related to RR v3, and we have an issue for that: #288.

Please feel free to reopen if there's something more. Thanks!

@vivaxy
Copy link
Author

vivaxy commented Feb 20, 2017

It just worked after my several updates.
I still didn't work out why it worked.

@andyearnshaw
Copy link

I've had the same issue without react-router. @bjudson's fix worked for me, are there any downsides to using this?

@IgorGee
Copy link

IgorGee commented Mar 6, 2017

I didn't have react-router installed at all while implementing react-hot-loader.

@bjudson's solution worked for me.

I think this issue should be reopened @wkwiatek.

@wkwiatek
Copy link
Collaborator

wkwiatek commented Mar 6, 2017

@andyearnshaw @IgorGee could you share some repository with minimal reproduction scenario?

I'll try to understand why you needed to add such a workaround.

In case of code from @akoskm and @bjudson (#240 (comment)) it should not be needed as the path says to webpack which code should be allowed to hot update. If you remove that path, then every change from outside will also cause hot update instead of full reload which potentially can have unexpected results.

@IgorGee
Copy link

IgorGee commented Mar 6, 2017

@wkwiatek sure, here ya go: react-boilerplate

Edit: To reproduce:

replace line 17

if (module.hot) module.hot.accept('./components/App', () => render(App))

and then try to change any text within App or Title

@wkwiatek
Copy link
Collaborator

wkwiatek commented Mar 6, 2017

Thanks for that. I quickly went through, and it seems your code is probably not using ES2015 imports from webpack. Following code fixes the issue:

module.hot.accept('./components/App', () => {
  const NextApp = require('./components/App').default
  render(NextApp)
})

However, it should not be required when using webpack ES2015 built-in imports. To have that, in your .babelrc you should have either es2015 plugin or latest (latest currently includes es2015).

This is how to use latest with module: false (https://babeljs.io/docs/plugins/preset-latest/#usagees2015):

{
  "presets": [
    ["latest", {
      "es2015": {
        "modules": false
      }
    }]
  ]
}

I'll mention it in the docs.

@andyearnshaw
Copy link

@wkwiatek that doesn't seem to be the problem for me. This is my .babelrc file:

{
    presets: ['react', 'stage-0'],
    plugins: ['react-hot-loader/babel', 'transform-es2015-modules-commonjs']
}

babel-jest requires the module stuff to be present, which is why I added transform-es2015-modules-commonjs. If I remove it, webpack compiles but it still doesn't hot reload. I'm a little busy with work this week so I'm not sure when I will have the time to duplicate the repo and trim it into a repro.

In case of code from @akoskm and @bjudson (#240 (comment)) it should not be needed as the path says to webpack which code should be allowed to hot update. If you remove that path, then every change from outside will also cause hot update instead of full reload which potentially can have unexpected results.

This makes it still sound like a bug. If you provide a path it doesn't update, if you don't provide a path it updates. Whether the issue is with webpack or react-hot-loader, I don't know.

@wkwiatek
Copy link
Collaborator

wkwiatek commented Mar 6, 2017

If you provide a path, and have ES2015 modules by webpack, then you only need to have this:

module.hot.accept('./components/App', () => { 
  render(App) 
})

But if you use babel transform for modules, then code looks like this:

module.hot.accept('./components/App', () => {
  const NextApp = require('./components/App').default
  render(NextApp)
})

It's not a bug, it's how it works with and without transforming es2015 modules. It's also stated in docs/migration guide. Of course you can say that any change in any file will trigger hot reload and hot update (not only the './components/App' path) but I can't say what consequences it may have.

@IgorGee
Copy link

IgorGee commented Mar 6, 2017

Thanks @wkwiatek, that .babelrc fix did the trick.

For anyone writing their webpack config in ES6, this babel configuration won't run your webpack config. I solved it by moving my webpack files into a separate directory with its own .babelrc.

@IgorGee
Copy link

IgorGee commented Mar 13, 2017

@wkwiatek, I've added a slight bit of complexity to my boilerplate and it goes back to the same behavior originally posted. But I do have additional information. All I've done is add a Root component as a parent to the Component I'm rendering.

react-boilerplate

  • If I change any text within the scenes/Home/index.js file, I get the 'Actual Behavior' @vivaxy originally posted.
  • If I change anything within the components/Root/ directory, the whole page gets refreshed.
  • Again, the if (module.hot) module.hot.accept(() => render(Home)) modification fixes the issue and behaves as expected.

@tsdexter
Copy link

thank you @bjudson I spent hours trying to make HMR work again - your comment seems to have fixed it for now.

@nukeop
Copy link

nukeop commented May 30, 2017

@bjudson - I spent like two days getting it to work before finding your comment, you're a lifesaver.

@nihiluis
Copy link

nihiluis commented Jun 4, 2017

my hot reload works now. but only once. after that the state in all components below Root is lost. any idea why?

if (module.hot) {
    module.hot.accept(() => {
        const NewRoot = require('./containers/Root').default;
        ReactDOM.render(
            <AppContainer>
                <NewRoot store={store} history={history} />
            </AppContainer>,
            document.getElementById('root')
        );
    });
}

@genomics-geek
Copy link

Thanks @bjudson - This resolved my issue as well

@Panoplos
Copy link

@bjudson That was exactly the problem!! Wow, I think a lot of the boilerplate samples need to be updated to reflect this. I wasted half a day chasing down this issue.

vanderhoop added a commit to stride-nyc/remote_retro that referenced this issue Oct 21, 2017
  - required a change in the parameters passed to module.hot.accept

  gaearon/react-hot-loader#469 (comment)
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