-
Notifications
You must be signed in to change notification settings - Fork 595
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
Hot module replacement? #295
Comments
Excited for this. This is probably a hacky idea, but the page should be re-rendered any time a reducer is fired, regardless of whether the state was updated. So you could inject a reducer that simply returns the current state, thereby not changing it but re-rendering the page anyway. But I'm sure there's a more elegant way if we change something in choo. |
Something magic (read: something I haven't figured out yet 😁 ) causes the React example to re-render, even though it seems to just be updating the class/prototype of the @timwis I'm going to give your suggestion of a noop-y reducer a try and see if that sorts us out! |
Ok, brace yo'selves… here's how HMR is achievable in choo right now:
module.exports = ud.defn(module, (state, prev, send) => {
return html`
<div>Blah</div>
`
}) (here's the nastiest bit!)
...
reducers: {
noop: (action, state) => ({})
},
subscriptions: [
(send, done) => {
setInterval(() => send('noop', done), 1000)
}
]
... So I'm going to try to distill all of this down to what I think are the two functional requirements needed to get a decent dev set up…
The final piece of the puzzle is knowing when to call |
Noting down @yoshuawuyts hot reload proof of concept here https://github.com/yoshuawuyts/hot-app-replacement/tree/choo I think this is interesting but as far as I can see it
? I think it would be cool if we could leverage these community projects and also benefit from actual hot-swaps of updated modules, rather than sending the entire bundle. I can see the benefit of the entire reload, if any views have any state that's not stored in a model obviously this would help. |
I'd favor the approach in hot-app-replacement because:
Hah yeah so that's about it - obviously you're free to do what you want, On Wed, Oct 26, 2016 at 6:59 PM Ben Gourley [email protected]
|
@yoshuawuyts ok you have me convinced! Can we put together a list of todos in order to have this packaged up and ready to go? I guess the only one reliant on you is the merge/publish of new barracks version? I'm happy to work on some of the other bits if we define what they are. |
Something like this? |
Sounds good @yoshuawuyts :D I might be able to get started on |
[Edit: I hit cmd enter too soon and posted this before it was finished 😬 ] So I've come up with a solution! Anyone want to try this out? npm i --save choo-resume hot-rld Attach the choo plugin. This saves the state on the window, and wraps the initial state to load from the window if it exists. const app = require('choo')()
const resume = require('choo-resume')
app.start('#app-root') Run the standalone SSE server. This watches the ./node_modules/.bin/hot-rld -b static/js/bundle.js -s /static/js/bundle.js In your server rendered html output the client that connects to the SSE server. const client = require('hot-rld/client')
const html = `<script>${client()}</script>` ConcernsSince this reloads the entire app bundle, any side effects of the app, including timers, event listeners and other subscription-like behaviour will happen multiple times. Crude example, causes a duplicate interval to be set up every reload: subscriptions: [
(send, done) => setInverval(() => console.log('boop'), 5000)
] I can't think of a good way of solving this, other than sticking the state in local storage and doing a full page reload. But then it's not really a hot-reload, more like a snapshot/resume tool (aside, that's not very hip and trendy, but it's still a useful and workable solution, perhaps we should run with that?). This is why my gut feel previously was to go the hot-module-swap because then you can just swap out the immutable parts of choo and be guaranteed to not have side effects. Thoughts❔❔❔ |
@bengourley oohhhh really digging this; might just work on top of this from choojs/bankai#86 - use the same client, but use Is there a way we could make this also work for CSS ? perhaps have different push channels that set the script and css individually? If we document the wire protocol then we could have compatible client and servers and like be super happy with all of it ✨ |
@yoshuawuyts I decoupled the cli/standalone server from the sse route handler, so if you pull in As far as CSS is concerned, yeah sure we could namespace the sse events into channels. FYI I don't know if you dug deep into the code, but I'm only sending tiny payloads (i.e. the path of the file that needs replacing, not the source of the bundle) and the browser is re-requesting the entire bundle from wherever it was served initially. |
I've published v1 of both https://github.com/bengourley/choo-resume and https://github.com/bengourley/hot-rld. @yoshuawuyts hot-rld now supports css too. |
Module reloading is part of bankai now too, couple with https://github.com/yoshuawuyts/choo-reload for SSE based reloading ✨ |
So I'm going to start with the the premise that Hot Module Replacement™ should be as easy and pluggable as https://github.com/substack/react-starter-hmr, with minimal change to the client application.
This is a rough-guide on what is required to get it set up:
npm i --save-dev browserify-hmr ud
watchify client.js -p browserify-hmr ...
ud.defn(...)
annotation to the part of the application to show which bits of the program are suitable for hot-reload (per screenshot above)My trouble is that with step
4.
I couldn't find a way with choo to force a re-render of the page's current state like in the React example. I got close in two different ways - forcing a reboot of the entire app (so reverting to initial state) or views updating the next time they were rendered (not insta-matically).If anyone knows the secret to getting this set up, please tell! Otherwise if a change is required in choo to facilitate this, let's figure it out? I think it's going to be something like exposing a way to call render/re-render, unless I'm missing something!
The text was updated successfully, but these errors were encountered: