-
-
Notifications
You must be signed in to change notification settings - Fork 418
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
Implement hot reloading #46
Comments
Yes, that would be extremely beautiful, and I thought about it today when having lunch. It should also be very possible in Cycle since everything is an event, so observing DataFlowNodes don't need to care if the observed DataFlowNode is being changed, as long as it issues events. However, I would leave this issue for a later stage, I want to first work on some issues that may bring major breaking changes to Cycle. |
Great, thanks. Let me know when you feel like ready to try! |
Being about to give Cycle a try. While currently using @gaearon s hot loader with react I wonder, if there is a suggestion or an attempt meanhwile on how to get hot loading accomplished in Cycle? |
Good question I haven't given thought to this in a while. Can @gaearon share some basic insights how hot loading works in general? Where does it hook in, and how does it swap old and new code? |
I suggest you use Webpack for hot reloading because it's the only bundle system that implements per-module reloading at the moment. Here are some docs that helped me get started: http://webpack.github.io/docs/hot-module-replacement.html They are somewhat confusing so if this doesn't help, I'm happy to take a stab at a proof of concept. The important part here is to first get hot reloading working in a sample project that directly uses Webpack's HMR API, and then figure out how to generate those HMR API calls based on what you know about the modules (e.g. inject HMR API calls into modules that export Streams, or something like that). |
Here's a React project boilerpate with hot reloading enabled and set up (ports, server, etc). You can remove |
Thanks a lot for this input! But, just to make clear, this type of technique is something that works as a separate Webpack plugin, right? It doesn't require changes to Cycle's core? Or, said in a different way, do you think it would be easier to implement hot reloading with React if you could just change some code in React? |
Hard to say before trying.
I'm not sure, but I don't think so. Most of the complexity in RHL was driven by the desire to support complex scenarios (e.g. hot-patch component method that was already passed to I think Cycle might have it much easier thanks to the lack of |
using webpack's hot reloading. works great so far. |
For anyone who wants an out of the box solution. https://github.com/Widdershin/cycle-hot-reloading-example The only issue still to be solved really is to restart the application with the same state when the code is changed. I think this can be achieved by implementing an API for drivers to record events from I'll take a crack at it soon. |
@gaearon I'll be having a look at this soon, if you already have any thoughts on how this might be be achieved would love to hear them. |
Niiice! I gotta take a look at this |
And now we have a proof of concept for proper hot reloading: https://gfycat.com/ZealousGreedyKronosaurus It does require adding a few methods to each driver, namely I can foresee a few problems with how |
The code for the above example is here: https://github.com/Widdershin/cycle-hot-reloading-example/tree/preserve-state |
@Widdershin That’s sick!!! In a good way. |
Isn't it totally different approach than in Flux or Redux? It's not only applying new version of application on current state, it's rebuilding state with new code from the same sources like before. I can see huge potential in this! 👍 |
That's correct @erykpiast. Since your |
Yes, it is! I'm soo excited. 2015-12-09 9:59 GMT+01:00 Nick Johnstone [email protected]:
|
@Widdershin Nick, this is the moment the world needs you. Go for it. |
😄 Thanks for the encouragment @staltz, but I have to sleep first 😉 |
Oh yes, New Zealand, I forgot... |
Coool! Glad to see it 👍 |
Okay, so today I got support for hot reloading in applications that use Still to do:
I'm keeping track of these issues over on cycle-restart: Once all that is done we can consider getting hot reloading merged. |
Great roadmap @Widdershin. When you say "history" I suppose you're not referring to https://github.com/cyclejs/cycle-history right? There might be another name we can give to this.
As a side note, notice how much hurdle a little bit of mutation and impurity can bring. |
Yeah, I say history because it's a record of all the events coming out of your We could call it "Hysteresis":
Any other ideas are welcome. |
I have a taste for odd names
I suppose you meant "coming out of your sinks"?
|
https://github.com/Widdershin/cycle-restart just had it's first release! After a random comment from @staltz about how I would support simple drivers, I changed up my approach a bit. I have created a function called
Where log is an array of occurrences to be replayed, in the format That driver can then be restarted, and we can have true hot reloading! Currently import {run} from '@cycle/core';
import {makeDOMDriver} from '@cycle/dom';
import {makeHTTPDriver} from '@cycle/http';
import isolate from '@cycle/isolate';
import {restart, restartable} from 'cycle-restart';
import app from './src/app';
const drivers = {
DOM: restartable(makeDOMDriver('.app'), {pauseSinksWhileReplaying: false}),
HTTP: restartable(makeHTTPDriver())
};
const {sinks, sources} = run(app, drivers);
if (module.hot) {
module.hot.accept('./src/app', () => {
app = require('./src/app').default;
restart(app, drivers, {sinks, sources}, isolate);
});
} If you want to try it out, clone down this github search example and play with the code: https://github.com/Widdershin/cycle-hot-reloading-example/tree/preserve-state Note that we need to tell @cycle/dom not to pause its sinks while replay is occurring. This (currently) the only information we need to implement replay for a driver. So! Now we have true hot reloading! Where to from here? Well, I would really like to make it easy to enable hot reloading in development. To that end, it seems ideal to extend the
Could something like that fit in to the adapters scheme that is currently being worked on? |
I have to emphasize, this is really good work, and highly appreciated @Widdershin. As soon as I get to experiment with it for a few apps I have and also the community doing the same, we can move it to
I agree, and that's doable. However, does it assume the developer uses Webpack or browserify? Even though these two are our main targets, we want to let it open if people want to use rollup or direct script in the browser.
Tangentially, but not exactly. It could fit in a good timing. Since we are reworking the architecture for run(), we can probably put auto-restarting inside |
@Widdershin could you give me a hand on getting an example working? Check I did some changes, following your https://github.com/Widdershin/cycle-hot-reloading-example, but there are some weird obstacles. Like To get cycle-restart in a good shape, we would need some easy setup instructions, and I'm trying to figure that out. |
Sure thing, I'll try have a look in the next day or so 😄 |
@Widdershin how "ready" do you consider |
I would say 90% ready. I've opened a milestone to track my last few TODOs https://github.com/Widdershin/cycle-restart/milestones/v1. One of the major pain points at the moment is having to provide options in some cases. It's likely that I'll add additional options in future, and it seems painful to ask users to update. Alternatively, configuration could be part of the driver, but that seems similarly troublesome. I am considering checking the |
Sounds a bit dirty, yeah.
Can you give an example? |
const drivers = {
DOM: restartable(makeDOMDriver('.app'), {pauseSinksWhileReplaying: false}),
HTTP: restartable(makeHTTPDriver())
}; Specifically |
Hmm, yeah I see. IMO the options are not so bad. Hot reloading is something for development-only anyway, and if it's a matter of one small option, it's ok, as long as it's clearly communicated in README (either of cycle-restart or cycle-dom or both). |
That doesn't stop us from thinking how to solve this, though. So if I rephrase: do have anything TODO until cycle-restart is 1.0 or "ready for primetime" (whatever how they call it)? |
The README is the biggest thing that needs to be done. I am also aware of one bug where cold drivers are indiscriminately converted into hot drivers, which causes some issues. That doesn't seem to impact any of the common drivers though so it's not as big of a priority. |
I removed "help wanted" just so people don't think this issue still needs an assigned leader. Because we already got one. :) |
This seems to be so userland, so old, so vague, that I think we can safely close it. Nothing stops us from using this space for discussions though. |
Agreed, I will open new issues if there's anything that needs to be changed On 31/08/2016 11:09 AM, "André Staltz" [email protected] wrote:
|
I implemented react-hot-loader for React (with core being extracted into react-hot-api) and I think it should be possible to implement the same for Cycle, especially considering its
this
-lessness.Would you be interested in helping out with this?
The text was updated successfully, but these errors were encountered: