Webpack hotreload for React/Redux not working--i think I know why


#1

This is the project, which I cloned from this one on Github.

When I make changes, as in the section “Is the hot module replacement really working?” of README.md it doesn’t hot reload.

Looking at the log, I see the “Listening at localhost:3000” appear each time I make an edit in a js file. I take that to mean that the node server is being killed and restarted on an edit–which sadly defeats the purpose of hot reload. I see that it does happen if I edit an HTML file or an SCSS file.

Questions:

  1. Is my analysis correct?
  2. if so, is there a way to work around this?

#2

Hey EmbeddedMike,

yes, your analysis is correct. We trigger a restart of the app each time any *.js file which is not in a directory called public is changed/created/deleted.

I am not sure about the purpose of hot module replacement in this particular case: does the restart of the server solve the same issue, or it won’t work for you?

UPDATE: nevermind, I watched the README and now I understand better.

Unfortunately, there is no easy way to disable the restart of the node server at the moment :frowning:


#3

Hello EmbeddedMike,

since you highlighted this specific problem, we decided it was worth fixing :slight_smile: you can now specify your custom “watch” rules for your project.

In your particular case, you can create a watch.json file in your project and add the following:

{
  "install": {
    "include": [
      "^package\\.json$",
      "^\\.env$"
    ]
  },
  "restart": {
    "exclude": [
      "^public/",
      "^dist/"
    ],
    "include": [
      "\\.json"
    ]
  },
  "throttle": 100
}

This should allow you to use the hot module reload function :slight_smile:

Let us know if you like it and if it works as expected!


#4

Wow! You guys! Setting the standard for a great response.

OK, we are halfway there. I cloned the original app to my Linux host to compare behavior. When I make a change on Linux, I get these messages in my server console:

webpack: Compiling...
Child html-webpack-plugin for "index.html":

webpack: Compiled successfully.

And then I get this in my browser console:

[HMR] Updated modules:
(unknown) [HMR]  - 410
(unknown) [HMR]  - 417
(unknown) [HMR]  - 414
(unknown) [HMR]  - 164
(unknown) [HMR] App is up to date.

HMR = Hot Module Reload

Now in the gomix console I get (time stamps removed)

webpack: Compiling...
webpack: wait until bundle finished: 
Child e[1mhtml-webpack-plugin for "index.html"e[22m:
webpack: Compiled successfully.

So almost the same, but not quite, because it does not hot reload, and after a delay it does a full page reload (boo!)

The browser console gives a clue (which I don’t quite know how to interpret).

It’s a series of messages like this:

abstract-xhr.js?96d9:132 GET https://localhost:3000/sockjs-node/info?t=1487187515003 
net::ERR_CONNECTION_CLOSED

About as many as the HMR messages in the reference version

Each message has a stack trace, which I can supply.

The “https://localhost:3000” comes from the webpack.config.js file, which says:

module.exports = {
    devtool: 'eval-source-map',
    entry: [
        'webpack-dev-server/client?http://localhost:3000',
        'webpack/hot/only-dev-server',
        'react-hot-loader/patch',
        path.join(__dirname, 'app/index.js')
    ],

I changed watch.json to restart the server when webpack.config.js changed.

Then I changed http://localhost:3000 to other things that I thought might work Like https://localhost:3000 and http://localhost and http://0.0.0.0?http://localhost:3000 and ‘https://tight-timpani.gomix.me/’ all to no avail.

Changing http to https did nothing.

Dropping the port just dropped the port on the error message.

And changing the host to anything but localhost resulted in no diagnostic, just a reload.

So at this point I am out of ideas. It seems like a WebSocket connection is getting set up, but then gives an error when the app tries to use it.


#5

Further info:

On the Linux version, when the web page loads I get these messages in the browser console:

[HMR] Waiting for update signal from WDS...
[WDS] Hot Module Replacement enabled.
[WDS] App updated. Recompiling...
[WDS] App hot update...
[HMR] Checking for updates on the server...

On the gomix version here’s the console:

[HMR] Waiting for update signal from WDS...
abstract-xhr.js?96d9:132 GET https://localhost:3000/sockjs-node/info?t=1487188674979 

and then some more errors


#6

Hey Mike,

I am out of office at the moment, I can check better later. Anyway, I think
that the problem now is the autoreload of the browser tab. You can disable
it by either opening your application manually instead of clicking the show
button, or by disabling the autorefresh by clicking on the menu on the top
right corner (there are two of them there: the one at the left) of the
editor and unticking the box related to autorefresh.

Let me know if this fixes the issue :slight_smile:

Thanks!


#7

Hi Emanuele,

Yess!!!

I got it to work.

i went back and retried my variations on this line:

webpack-dev-server/client?https://localhost:3000',

and I was able to get a bit further by changing to:

webpack-dev-server/client?https://tight-timpani.gomix.me',

But it was still reloading the page too fast. I created a new project and then deleted it and then came back and now it works. So there must have been some state hanging around. Either that or I had done something dumb.

Anyway, it works!

Is there a way that I can get the URL for the app programatically?

Mike


#8

You can use the environment variable PROJECT_NAME by referencing it in your app as follows: process.env.PROJECT_NAME. That will get your sub-domain which you can use to construct the full URL.


#9

Gareth

Thanks. It works!

Is there a document somewhere that has this? I’d also like to document the watch.json thing that Emanuele told me about (or even did).

Mike


#10

Yes, I’ve updated the FAQ with details: http://gomix.com/help/faqs


#11

Thanks, Gareth.

Loving gomix and the team!

So one last feature request that would make the experience of me and other Hot Module Replacement (HMR) fans in the gomix community even better. That would be to turn off auto-refresh for the project. Auto refresh is great in general but is actually way worse than HMR which you can see for yourself if you try the project. (Here’s an invite link)

To get the full experience, open the app (Don’t forget to turn off “reload on changes” in your profile) then in the file edit app/components/App.js Edit the contents of the H1 tag. Bang! it updates. And the rest of the state is unchanged.

So the problem is that whenever I re-open the project, I have to turn off update on changes.

I am planning on making this a template for people to remix and add their own to, and I will write a post for the community so people looking for this can find it.

The problem will be that when others remix the project, they are going to have to remember to turn off reload. (I can probably add something to the project so that if it reloads too quickly it will tell them. But I’d rather not go there.

If you’re not fully convinced of the awesomeness of HMR, (and even if you are) I encourage you and anyone else watching the thread to watch the video linked below. The idea of tools like gomix and JSFiddle, and JSBin and so on is to let people do development and get FAST feedback. Dan Abramov has taken it to the next level and the productivity difference is quite astounding. (It’s like going from an environment without auto reload to one with. You don’t know what you are missing until you’re not missing it.)

You can do Hot Module Replacement with WebPack in other situations, so it’s not just React/Redux specific. But I think the whole workflow together is pretty cool.

Happy watchings.

And again thanks for a great environment and legendary support.


#12

Hey EmbeddedMike,

two things that we’ve been talking about:

  1. If you turn off auto refreshing/updating in a project, we should save that preference and remember it the next time you load the editor
  2. turning off auto refresh by default (so the box would be unchecked) and letting ppl check it on if they want

we’ll do #1 for sure, and are still discussing whether to do #2 (strong chance that we will though)


#13

quick update: we decided to do #2 : auto-refresh is now turned off by default


#14

Hey, thanks for the update.

It serves my need so I’m happy.

But I don’t think it’s the best thing for all projects and users.

If there’s an easy way to tie it to watch.json that would be the best solution. For some projects, auto-refresh is the right thing. For people who use JSFiddle some others, it MAY leave people scratching their heads. Many of them have “refresh” visible at the top and not buried in a menu. So that would be the next best choice.

Still, appreciate the fast response.

And re-recommending that people watch Dan’s video. I found it enlightening and inspiring.


#15

Hey Mike,

thanks for all the useful information :slight_smile: We added your ideas to the todo list. It’s actually a very good idea to tie the autorefresh to the watch.json so that you can actually disable it from there if it does not apply to your project!

Thank you again :slight_smile:


#16

Hey, Dan from React team checking in. :slight_smile:

There’s an official tool called Create React App that we recommend people to use.
It would be great if project bootstrapped with it could work on Glitch.

This is not related to hot reloading per se, but I bumped into the same problem.
If you open this project built with Create React App, you’ll notice reloads are very slow.

If you look at the logs, you’ll notice this is because Glitch stops the server on every file change:

Compiling…
5:31 PM

Starting the development server…
5:31 PM

But Create React App development server assumes incremental updates. If only Glitch didn’t kill the devserver, reloads would be so much faster. Create React App already takes care of recompilation on file change.

I imagine the solution as adding another checkbox called “Restart Server on Changes”:

Now, to make it clear, there’s very little in a product that annoys me more than options or checkboxes. But in this particular case I feel like it’s making usability much worse, and with the shift to bundler-based workflows, it’s going to keep coming up, whether people are using React, Angular, Ember, or something else. It would be great to address built-in watcher paradigm in the UI directly, especially since workarounds like watch.json aren’t particularly discoverable.

Thank you for considering this request!


Create React App Support
#17

​​
Dan,

I’m a big of your work and I think redux is one of the most brilliant
things ever.

I’ve been working on a few projects on glitch that incorporates Redux,
Redux Dev Tools, with HMR plus browser-sync and more.

To see it in all its glory, make sure you turn off “Refresh app on changes”
(the menu with your github icon, on the top right.

The key to making it behave it watch.json

kitchen-sink-reference https://glitch.com/edit/#!/kitchen-sink-reference is
my current reference project. The readme gives its provenance. It is not
quite up to date–missing a link to the current github repository.

Regards,
Mike Wolf


#18

I still can’t figure out how to make a simple Parcel app working with HMR on this app.

The app rebuilds fine, and he browser console’s output says it can’t connect to apps websocket port

Is there a way to make this work?


#19

Your browser won’t be able to connect to port 38854 there. It would be hitting port 38854 on our proxy, and we’re not listening there. If you get your application to listen for websocket connections on process.env.PORT, then wss://parcel-react.glitch.me will connect to the application.


#20

It seems that I would need two ports for that. The command would then be something like

$ parcel --port $PORT --hmr-port $PORT2

Is there an undocumented way to do this?