lhapaipai / symfony-vite-dev

Monorepo for symfony-vite development
https://symfony-vite.pentatrion.com
Other
21 stars 20 forks source link

Disable HMR for certain URLs #31

Closed ehaeusler closed 1 month ago

ehaeusler commented 3 months ago

Is it possible to disable HMR/Page-Reloads for certain "outer" URLs or via param in the twig-helprs?

In my case, I use the symfony-vite-bundle for developing the frontend for a cms (for example: Pimcore) by using tailwind. So I need the refresh function for .twig.html Files. Especially since tailwind needs to know, when those files are edited so it can extract the necessary classes. But at the same time I have the cms admin backend open in a different tab and since this particular cms uses a live preview type of editing, it always reloads the page in the admin backend as well, which also automatically focuses said tab because the backend asks if I really want to reload without saving changes, which results in horrible DX.

I can differentiate inside the twig-Files, if the template gets displayed in editmode or not, maybe I could pass some type of flag to deactivate hmr?

lhapaipai commented 3 months ago

I @ehaeusler, have you seen that you can "enable/disable" the "refresh" of the browser when you update a twig file but this option can accept an array of string. vite-plugin-symfony reference refresh

import symfonyPlugin from "vite-plugin-symfony";

export default defineConfig({
    plugins: [
        symfonyPlugin({
            refresh: [
                "templates/only-this-dir/*.twig"
            ]
        }),
    ],
})

but if I understood correctly this is not your expectation. yours would rather be to choose in your browser whether you wish to activate HMR or not depending on your tab.

http://localhost/posts/1
http://localhost/admin/posts/1

<html>
<iframe src="http://localhost/posts/1?hmr=false"></iframe>
<html>

I don't know if it's possible. from my point of view I would advise you to deactivate the refresh option of the vite-plugin-symfony plugin and that you look in the vite doc or if a specific plugin would do the expected behavior.

lhapaipai commented 3 months ago

I think, it can be a plugin we listen server side on files changed and send custom event to the client. on the client side you should be able to listen to these custom events and conditionally choose whether or not you choose to refresh the page.

ehaeusler commented 3 months ago

@lhapaipai Thank you for your suggestion. The problem with disabling the refresh-function is, that vite and therefore tailwind no longer get notified of file changes. That means if I add/remove/change tw-classes inside a twig-template, those changes won't be reflected in the css.

for reference: backend

Thats the admin interface and the area surrounded in red is an iframe of the frontend-page which includes the styles/scripts generated by vite and included via vite_entry_script_tags. And as you can see after every change it asks if I really want to reload - which of course is not the problem of this neat bundle here, but rather an annoying side effect when I'm working on both things in parallel. 😄

I'll check those custom events, thank you.

lhapaipai commented 3 months ago

yes it's annoying I have the impression that looking at the "vite" side, it's going to require a lot of work... and unfortunately I don't plan to do that for this plugin. it would be worth a dedicated plugin.

another track. this popup is linked to the beforeunload event of the window object. I know it is possible to deactivate it completely in the browser. (for example it is: dom.disable_beforeunload in Firefox. or check if it's possible not to register this event when dev in the pimcore source code ?

ehaeusler commented 3 months ago

Great hint with the beforeunload-Event. In this case I just override window.onbeforeunload since the original event listener is registered that way and I can prevent the execution of the confirm dialog. Thank you very much for your time and excellent pointers :)

ehaeusler commented 3 months ago

A little addendum for this case if anyone has use for it: After some more research I went with a different approach. I am now listening for the vite:beforeReload Event and prevent the reload from happening. It's not the cleanest little workaround but I not only prevent the confirmation dialog from happening, but also the reload itself so I don't accidentally lose any data. Therefore I have full control over the reload handling in the backend and the DX experience during frontend development is untouched.

The method is described right here: https://github.com/vitejs/vite/issues/5763#issuecomment-1974235806