webpack-hot-middleware
webpack-hot-middleware copied to clipboard
Idea: double-save to refresh browser
tldr; Save a file once, everything's normal. Save a file twice (like a double-tap), browser refreshes.
Scenario
_Web app that shows how much of a product is left in stock.
- I'm viewing a product page: 1 left in stock.
- I add it to my cart.
- Open a separate window, viewing that same product, I still see 1 left in stock, even though it's in Step 1's cart.
- I realize there's a bug in my API from showing the correct total.
- I fix the bug in the API, save the code, HMR reloads the server-code. The browser still isn't in sync, though without a refresh.
- I save the code again, webpack doesn't build anything (no changes), but the browser HMR sends a
reloadevent and I correctly see 0 left in stock.
I'm asking here because webpack-hot-middleware is what's triggering reload events in the browser and seems like a likely place to be able to trigger the event.
Cool DX, but doable? I'd be happy to help if you can help me figure out where to even do this.
Interesting idea, it's possibly doable - depending on what the granularity of the file change event is after a save.
At the moment I just let webpack watch the filesystem, so we would need to reach into webpack and grab the watchpack instance somehow - then compare timestamps of change events.
Another similar option might be to have the middleware expose an HTTP endpoint which sends a force-reload message, and then have editor plugins ping that endpoint on a custom keybinding.
@glenjamin Makes sense to me. I've finagled with Webpack a bit, so if I can work it out would you be open to a PR?
(If it doesn't fit within this project, it can likely be a plugin instead).
I'm happy to take a PR, possibly behind an option that's off by default initially.
@glenjamin I <3 you. I'll see what I can do :)
@matthiasak Pinging you since this came from our discussion!
@ericclemmons @glenjamin
I don't have a ton of experience with the lower internals of webpack or webpack-hot-middleware, but I imagine you'll need to keep track of file hashes for the server-side code separately from the client-side.
In https://github.com/matthiasak/universal-js-boilerplate-v3 I have two configs generated by my webpack.config.js. I use webpack-hot-middleware (WHM) to manage the client-side - and the webpack --watch CLI command to manage the server code. Thus, If I want WHM to track changes in the server-side code, I'd need an option kinda like serverEntry to track those changes and check subsequent file hashes against the prior version.
app.use(require("webpack-hot-middleware")(compiler, {
serverEntry: ['/path/to/server-entry-file.js']
}))
But this might have some extra overhead in-terms of watching the server files from both the WHM and webpack --watch. Perhaps WHM can take an optional pointer to another webpack instance to hook into its changes?
let serverBundler = webpack(serverConfig)
app.use(require("webpack-hot-middleware")(compiler, {serverBundler}))
WHM can't really do anything useful with a server bundle.
There would be 2 parts to an implementation of the feature suggested here:
- Hook into webpack/watchpack events to figure out when the reload-condition is met
- Send a message down to the connected clients to force a reload
If you also wanted to force a refresh after server-side changes then that would hopefully only need (1) to be hooked up to the server bundle, and an appropriate method called on the middleware instance.
I figured it made the most sense to solve it in two steps:
- [ ] Double-save to force reload for client-side bundles.
- [ ] Double-save to refresh browser when server bundle is saved.
As noted, they'll require 2 different solutions.