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

Updated module requires browser refresh #515

Closed
rpoitras opened this issue Mar 12, 2017 · 16 comments
Closed

Updated module requires browser refresh #515

rpoitras opened this issue Mar 12, 2017 · 16 comments

Comments

@rpoitras
Copy link

rpoitras commented Mar 12, 2017

Description

JSX changes not triggering browser update.

Expected behavior

Make changes to some JSX while webpack dev-server is running. Changes are detected. App recompiles. Browser is updated with changes without a full refresh.

Actual behavior

Make changes to some JSX while webpack dev-server is running. Changes are detected. App recompiles. Browser does not update. Changes are reflected only if the browser is refreshed.

Environment

React Hot Loader version: 3.0.0-beta.6

  1. node -v: v7.5.0
  2. npm -v: 4.1.2
  3. Operating system: Ubuntu 16.04.2 LTS
  4. Browser and version: Version 57.0.2987.98 unknown (64-bit)
  5. Operating system(2): macOS Sierra 10.12.3
  6. Browser and version(2): Version 56.0.2924.87(64-bit)

Reproducible Demo

https://github.com/rpoitras/sample-app (with react-router 3.0.2)
https://github.com/rpoitras/sample-app/tree/react-router-4 (with react-router 4.0.0)

@rroslaniec
Copy link

webpack/webpack-dev-server#100 (comment)

@mongjong59
Copy link

mongjong59 commented Mar 19, 2017

Having a similar issue with a similar environment:

  1. react-hot-loader v3.0.0-beta.6
  2. react-router v4.0.0
  3. webpack v2.2.1
  4. react v15.4.2
  5. redux v3.6.0
  6. webpack-dev-server v2.4.2

All things look good when I make a change:
Updates are logged in console like

[HMR] Updated modules:
[HMR]  - ./components/Base.js
[HMR] App is up to date.

hot-update.js is loaded
But the DOM is never updated.
And my code is very similar to this demo except I run the dev server with babel-node server.js

@mongjong59
Copy link

mongjong59 commented Mar 20, 2017

@rpoitras
I get it working now. My problem is that I didn't render my component correctly.
I changed it from

const element = (
  <AppContainer errorReporter={consoleErrorReporter}>
    ...
  </AppContainer>
)
if (module.hot) {
  module.hot.accept("components/Base", () => { 
    ReactDOM.render(element, document.getElementById(domNodeId))
  })
}

to

const renderApp = Component => {
  const element = (
    <AppContainer errorReporter={consoleErrorReporter}>
      ...
    </AppContainer>
  )
  ReactDOM.render(element, document.getElementById(domNodeId))
}
if (module.hot) {
  module.hot.accept("components/Base", () => { renderApp(App) })
}

And injectTapEventPlugin() shall be moved out of the component that should be hot updated.

But these seem fine on your branch. But your entry files are a bit different from those working boilerplates. Try to put react-hot-loader/patch, webpack-dev-server/client?http://localhost:8080, webpack/hot/only-dev-server before your source entry file in the same chunk

You can try to follow this demo (the most helpful one AFAIC) as much as possible.

I guess everyone did something wrong differently. But the actual problem here is the logging. It would be nice if it's possible to log some errors in such situations.

@rpoitras
Copy link
Author

Thanks for the suggestion @retroalgic. I just tried it. But the behaviour remained the same. I'll look closer at the demo you linked. Maybe I'll see something.

@rpoitras
Copy link
Author

rpoitras commented Mar 20, 2017

@retroalgic
I tried many variations on the HMR setup between webpack config and cmd line. Settled with the webpack configuration style. Still no luck. I don't see anything in the bare-minimum demo that helps me.

I have basically the same setup in both the react-router 3.0.2 and react-router 4.0.0 branches.

// in webpack.config.js
webpackConfig.entry = {
    js: env.prod ? [
      'babel-polyfill',
      PATHS.app  // main index.js app entry point
    ] : [
      'react-hot-loader/patch',
      'webpack-dev-server/client?http://' + HOST + ':' + DEV_SERVER_PORT,
      'webpack/hot/only-dev-server',
      'babel-polyfill',
      PATHS.app
    ],
...
webpackConfig.plugins = [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NamedModulesPlugin(),
...
webpackConfig.devServer = {
    hot: true,
...

// package.json
...
"scripts": {
    "start": "webpack-dev-server --host 0.0.0.0 --progress --env.dev --watch-poll",
...

@mongjong59
Copy link

@rpoitras
One way to debug this is to first setup a very minimal implementation like a Hello World. Make it work first and then implement with your actual app.
(actually we are not supposed to discuss usage issue here, the issue with this package is the meaningless logging)

@Anima-t3d
Copy link

I had the same issue. I solved it by requiring the module again as described here:

if (module.hot) {
    module.hot.accept('./App', () => {
        const NextApp = require('js/App').default;
        ReactDom.render(
           ...

@mongjong59
Copy link

mongjong59 commented Mar 23, 2017

@Anima-t3d
That usually means there's something wrong with your .babelrc. You need to disable modules transpiling effectively.
@rpoitras At least you need to replace "airbnb" with ["airbnb", {"modules": false}] in your .babelrc (or just copy and paste .babelrc from one of the demo if it's okay for you)

@rpoitras
Copy link
Author

@retroalgic thanks, my .babelrc has the modules: false

@Anima-t3d I've tried that before with no luck. But I thought I don't recall using that implementation with a setup that included react-router-4. And voila, it works!!! 🥇

Still does not work with react-router-3 on my setup. But that's fine with me. I'll keep moving the ball ahead and move to v4.

Thank both of you so much. I've spent countless hours trying to get this to work.

@rpoitras
Copy link
Author

This can be closed, example in this working demo

@Anima-t3d
Copy link

@rpoitras This is my .babelrc:

{
	"presets": [
		["es2015", {"modules": false}],
		"react-native",
		"stage-0"
	],
	"plugins": [
		"react-hot-loader/babel",
		"transform-class-properties",
		"transform-es2015-spread"
	]
}

@rpoitras
Copy link
Author

@Anima-t3d I'm using:

{
  "presets": [
    "airbnb",
    ["es2015", {"modules": false}],
    "react",
    "stage-2"
  ],
  "plugins": [
    "transform-class-properties",
    "react-hot-loader/babel"
  ]
}

@wkwiatek
Copy link
Collaborator

@rpoitras airbnb preset has also modules in it, so if you want to use webpack 2 modules, then you have to put ["airbnb", {"modules": false}] as @retroalgic suggested. If you don't have it, then you need to re-require it.

I hope, it's solved now, thanks guys for your help!

@rpoitras
Copy link
Author

Ah, I saw it with es2015 and missed @retroalgic was pointing out to add it to airbnb. Thanks @wkwiatek for getting me to open my eyes. 👍

@vraa
Copy link

vraa commented Nov 7, 2017

Able to get it working by requiring the module again:

// Webpack Hot Module Replacement API
if (module.hot) {
    module.hot.accept('./containers/app', () => {
        require("./containers/app");
        app.render(AppContainer);
    })
}

However, the changes do not get applied on the fly. I need to go back to a different component and then come back to a changed component to see the changes. Anyway, this is way better than a full page refresh and losing the entire application state. Thanks to @Anima-t3d for the tip.

@theKashey
Copy link
Collaborator

@vraa - you forget to update a local variable

App = require("./containers/app");

Require by it own does not do anything.

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

7 participants