FredKSchott / esm-hmr

a Hot Module Replacement (HMR) API for your ESM-based dev server.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

provide access to the module being replaced

wighawag opened this issue · comments

Currently with snowpack there is no way to get runtime access to the module where the js reside.

So if the import.meta.hot.accept could also provide the previousModule as argument to the callback, this would allow the reload to perform logic based on the previous module

like for example

 if (import.meta.hot) {
        import.meta.hot.accept(({module, previousModule}) => {
            for (const field of Object.keys(module)) {
                const newPrototype = Reflect.getPrototypeOf(module[field]);
                Reflect.setPrototypeOf(previousModule[field], newPrototype);
            }
       });
}

I just realised I can do that instead:
(importing the currentModule via url to get access to its fields)

async function HMR() {
    if (import.meta.hot) {
        const previousModule = await import(import.meta.url); // get access to current module
        import.meta.hot.accept(({module}: any) => {
            for (const field of Object.keys(module)) {
                const newPrototype = Reflect.getPrototypeOf(module[field]);
                Reflect.setPrototypeOf(previousModule[field], newPrototype);
            }
        });
    }
}
HMR();

That works but giving access to previous module directly in the call back is more elegant

commented

@wighawag, interesting, couldn't get the above technique to work at my end. By any chance, do you have a working example?

Does Reflect prototype get/set work as mentioned above? I tried the above and the [[FunctionLocation]] didn't really point to the updated module's exports.

commented

Thanks @wighawag. I tried the plugin and didn't had luck making it work as expected.

I have reported an issue with reproduction & video demo at the plugin's github page - wighawag/snowpack-plugin-hmr-inject#1