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
Opt-in to disable page reload when using HMR #418
Comments
👍 EDIT FROM SCRATCH: Thought it through a bit more and I think it largely comes down to if you're working with a stateful or stateless project. If you're working with a very stateful project you likely don't want it to reload automatically at all (at least I don't), whereas changes that can be hot-patched should be patched. But if you're working with a rather stateless project you want it to reload all the time, not reloading (when possible) is a bonus. So I propose an option for whether or not "reloading" is at all allowed. |
What you really want is webpack/webpack-dev-server#42... |
@sokra Definitely, but I'm pretty sure I also would want to be able to turn off reloading entirely, I do not want it to reload if I make an irrelevant change to a non-hot-replaceable file. |
I agree; it's also a matter of preference, as most of my team hate auto reloading. They're used to refreshing when they feel like it. For stateful project, auto reloading is quite irritating. For them, HMR is a nice bonus when it's possible, but not at the cost of constantly losing their state due to irrelevant edits. |
Agreed. HMR is great (e.g. for editing styles), but auto-reload is not always desired. |
Currently we cannot recover from an exception during hot update, but you can disable refreshing by writing you own HMR management code instead of using the prepared |
Bah! I never realized it's that small. OK :-) |
And it's mostly logging ^^ |
Yep, I've already written my own 😀 |
For posterity, this is what I use for the moment:
|
I have similar code. The only problem so far is that after one failed update (that I ignore inside my server), updates can't be applied anymore. Apparently |
So you don't restart your app on failure (like with |
I don't—it's inconvenient to lose all state due to a simple typo. I may have style modifications or useful logs in Chrome devtools that will be lost because of that. |
That's true, but unless you have stateless views it's really hard to just swap out modules. Seems like one of your updated modules didn't provide an update handler via |
@jhnns Not sure I'm following you.
But it already works! This is precisely the problem react-hot-loader is solving (for React views). I just don't want an occasional typo to either reload the page or disable HMR. I want the typo to be ignored till next HMR. |
It possible to catch the syntax errors in the accept handlers... Example: // Accepting another module
module.hot.accept("module", function() {
try {
require("module");
} catch(e) {
// Some fallback
}
}); // Accepting self
module.hot.accept(function(err) {
// Some fallback
}); |
@jhnns There are tons of cases where it will "fall out of sync" and error in practice, we're not "arguing" against that. But if I spot a minor mistake or grammatical error in my If I add/change/remove a non-hot-updateable To put it differently, assume that |
The first example is how I used to do it before I rewrote the loader to avoid pitch stage. It allowed me to catch the error. In your second example, how would you prevent HMR entering "fail" stage and refusing to accept future updates? |
It only goes into |
Ah, so there's a difference between |
|
I think these examples refer to accepting itself—I'll give it a try as it seems to solve my problem (although this issue is about webpack-wide support for disabling page reload). As for why @syranide uses HMR, I think it's for the same reasons that I do: with react-hot-loader you get no-refresh hot reload for React components (like in this video). The whole point is avoiding refreshing. |
@jhnns I see HMR as an awesome feature to avoid having to do lots of changes in the blind and then reload, not as a feature to reduce the time between visual updates (by avoiding reloads). I think neither is wrong, but the second makes no sense to my workflow for complex apps; I do not want to throw away all my app state because I made an insignificant change that I don't need to preview right now. I.e. if I'm working on something mostly visual and stateless, please just reload for every change. But if I'm working on stateful application code then I absolutely don't want it to reload unless I say so, I accept the consequences of making potentially incompatible changes and reloading myself when necessary. |
@sokra Thanks, that's what I did: gaearon/react-hot-loader@f3485dc |
@jhnns It's covered by the "copy-pasteable" server code, that's where the reloading takes place. It's easy enough to disable reload and/or tailor to your own liking, but |
@sokra You're the best! 👍 |
I see! Really appreciate you watching this thread and making changes to bring us hot reloading nirvana. |
I just tried |
@gaearon 😄 |
See webpack/webpack#418 (comment) for context
It seems like I've been doing a silly thing for a long time. If you use React Hot Loader with Which is awesome because with |
Oh well, I was wrong. HMR breaks if you don't use NoErrorsPlugin and misspell a dependency name. Bummer. I'll probably create an issue because I'm not sure why it happens this way. |
Just wanted to say this discussion is awesome, helped me understand webpack better, and saved me a few hours at work. Thanks all. |
The |
I'm not alone having the issue with the noErrorsPlugin: webpack/webpack-dev-server#655 When using the noErrorsPlugin, after making an error and then fixing it, module.hot.status() returns "check", when it should return "idle". So, basically it gets stuck somewhere, I can't figure out. |
@koddo sadly the fix for this issue only went into Webpack 2 beta. I do understand bug fixes going into 2 so it gets out the door more quickly but I am reliant on webpack v1 and so are a lot of people who feel more comfortable on a stable version. |
I haven't looked at the commit that fixes it in version 2, so I'm not sure how complex backporting the fix would be. |
@mikeengland, I've seen it, and that would be hard, for sure. But my monkey patch works for me. Will use it until v2. |
I know it's immature but I temporarily solved it by placing a return in the beginning of reloadApp() :P |
Four years later, @sokra showed me a solution that seems to do exactly what I wanted: function hotErrorHandler(err) {
require.cache[module.id].hot.accept(hotErrorHandler);
}
module.hot.accept(hotErrorHandler); 😄 |
It's never too late... |
@gaearon I've been trying for a couple of hours to get this working but I can't. Is there no way to have an if (module.hot) {
module.hot.accept("./server", () => {
serverInstance.close();
serverInstance = createServer();
return serverInstance;
});
} |
For people trying to figure out how to correctly let serverInstance = require("./server").createServer();
if (module.hot) {
module.hot.accept("./server", () => {
try {
const updatedImport = require("./server");
serverInstance.close();
serverInstance = updatedImport.createServer();
}
catch (err) {
console.log(err);
}
});
} |
When HMR update fails, it forces a page reload.
This may be desirable for consistency, but most of the time this is caused by a simple syntax error, and I'd like to error to just appear in console. When I fix the error, another HMR update will come and "fix" the system anyway.
When react-hot-loader used a pitch loader, it just put HMR-updated require inside a try-catch.
Now that I refactored it to be a simple loader (no pitching), I no longer have the ability to
catch
syntax errors in the breaking module.Can we have a way to disable page reloads altogether? I guess making it opt-in and logging something like "The system is in inconsistent state" is fine with me.
cc @syranide
The text was updated successfully, but these errors were encountered: