Open LarsDenBakker opened 3 years ago
Hey Lars, thanks for starting the discussion. Is there a reason why you can't do something like this?
import { component } from 'haunted';
import hot from 'hot-web-components';
function App() {
...
}
const AppElement = hot(component(App));
ie, wrap the class that component() creates?
@matthewp I did some rework, and indeed that's how it works now.
I got it working now for Haunted using a small patch: https://github.com/open-wc/open-wc/blob/master/packages/dev-server-hmr/src/presets/haunted.js#L3
Ideally I would like to patch the hotReplacedCallback
onto some base class, would it possible to expose this from within Haunted? I could patch it onto each haunted component individually, but a user might be using multiple component base classes so we'd have to detect that something is a haunted component which makes things more complicated.
A bigger problem is updating the scheduler with a new renderer. Would it be ok to expose the renderer as a static field on the class? Then I could grab it there. I was able to work around it by instantiating a temporary element and getting it from the instance.
Ideally I would like to patch the hotReplacedCallback onto some base class, would it possible to expose this from within Haunted?
Not sure I follow, what change are you suggesting?
A bigger problem is updating the scheduler with a new renderer. Would it be ok to expose the renderer as a static field on the class?
Yeah that's fine, but the scheduler is a privatish field at the moment. We should probably make it public if library are going to depend on it.
@LarsDenBakker Don't know if you are still looking into it. This is how I got esm hmr working in my system.
const tag = 'my-counter';
const Module = await import("/assets/my-counter.js");
document.querySelectorAll(tag).forEach((node) => {
const Scheduler = class extends BaseScheduler {
constructor(renderer, frag, host) {
super(renderer, host || frag);
this.frag = frag;
}
commit(result) {
render(result, this.frag);
}
}
node._scheduler = new Scheduler(Module.default, node);
node.connectedCallback();
}
Hi there! At open-wc we started working on hot module replacement with es module workflows: https://open-wc.org/docs/development/hot-module-replacement/
So far it works for class based components. We're now looking into how we can support this for function based components.
The idea is that the web component base class implements a static and/or instance
hotReplaceCallback
function which does the actual replacement. Since you don't want this code to end up in production, projects can make it available through a module which patches the base class.Since haunted in the end creates a class, I was hoping to do the same here. However one issue I ran into is that the class is created in a closure, so I can't inject any code into it. Also, the renderer function is only available within the closure.
I made some modifications to the source code and the basic features are working, so that looks promising. I did run into some issues with preserving state between replacements, so that would be something to look into.
Is this something that would be interesting to support in haunted?