vite icon indicating copy to clipboard operation
vite copied to clipboard

Allow preventing default actions of client.js

Open Artur- opened this issue 2 years ago • 9 comments

Clear and concise description of the problem

Some users have brought up that they want live reload temporarily disabled.

The use case is that they are modifying styles in the browser inspector instead of modifying the project files. Once they are done with styles modifications, they go through their changes and copy them to the project files. If you have live reload enabled when you do this then a full page reload can take place after the first changes are copied to a project file and that file is saved. When this happens, all remaining changes are lost.

Suggested solution

Allow listeners like vite:beforeFullReload to call payload.preventDefault() which will stop client.js from taking any actions.

Alternative

No response

Additional context

No response

Validations

Artur- avatar Nov 19 '21 13:11 Artur-

You can disable HMR by set server.hmr to false.

ygj6 avatar Nov 20 '21 06:11 ygj6

Ah, I forgot to mention that it would be preferrable to do it runtime through a UI control in our case

Artur- avatar Nov 20 '21 06:11 Artur-

The scene is a little too special. Maybe you can put a breakpoint on @vite/client to stop the page reload.

ygj6 avatar Nov 20 '21 08:11 ygj6

I can agree that it is quite a special case and might be solvable with the conf option.

There is another case also where this has come up which is:

  1. You are on page /
  2. You click to navigate to /hello
  3. The router starts loading a JS bundle needed by /hello and when finished, updates the URL and the view content
  4. Before the JS bundle is loaded, Vite does a page reload

Result: you are still on / after navigating to /hello which is quite unexpected

Artur- avatar Nov 20 '21 09:11 Artur-

Does anyone know if it's possible to get the method suggested by @cdauth in https://github.com/vitejs/vite/issues/6695#issuecomment-1069522995 to work in Vite 5?

I've upgraded to 5.1.1 and despite throwing in vite:beforeFullReload the page still refreshes.

If I downgrade to 4.5.2 it works.

jacksleight avatar Feb 13 '24 16:02 jacksleight

I also encountered the same issue as @jacksleight .

I'm just trying Vite out and considering to switch from Webpack. Browser page refresh is a blocker for me.

Refreshing the browser resets all state and is an incredibly intrusive action.

I get the concern about leaving the app in a supposedly inconsistent state with the code - but why take the paternalistic approach? I am not a newbie. I know what I'm doing and I want to be in control (without losing HMR altogether).

obeobe avatar Feb 17 '24 21:02 obeobe

@jacksleight -

I found two workarounds:

  1. Relatively clean but annoying: prompt before browser refresh. It's annoying because it will show an alert, but at least it will give you a chance to click on "Cancel" and avoid the refresh. Just add this code in your application initialization:
window.addEventListener('beforeunload', function(e) {
	e.preventDefault();
	e.returnValue = '';
});
  1. Dirty but not annoying: modify Vite code in node_modules/vite/dist/client/client.mjs and add a break after `case 'full-reload': image

Obviously this will need to be re-applied when updating Vite...

Note that you need to restart the server for this change to take effect.

obeobe avatar Feb 17 '24 21:02 obeobe

Here is a very hacky workaround that will definitely not work forever:

if (import.meta.hot) {
	// Prevent full reload, see https://github.com/vitejs/vite/issues/5763#issuecomment-1974235806
	import.meta.hot.on('vite:beforeFullReload', (payload) => {
		payload.path = "(WORKAROUND).html";
	});
}

cdauth avatar Mar 02 '24 03:03 cdauth

@patak-dev Is there any chance you'd reconsider https://github.com/vitejs/vite/issues/6695 independently from this issue?

That issue was closed in favor of this one, but I feel that one has a smaller scope than this issue and like @cdauth I would prefer to simply run my vite server with full reloads completely disabled. (Though unlike @cdauth, I don't care if this also disables hot reloads - I already run with server: { hmr: false }, but I still get the frustratingly disruptive full page reloads when switching between branches.)

Let me elaborate on why these full page reloads can be so painful: Imagine you are working on the current code and you notice some unexpected behavior. You want to keep your app loaded in this state so you can interact with it, but you also want to go check out an older revision and check the behavior there side-by-side. So you git checkout the old revision and--OOPS! Vite just reloaded the page you wanted it to leave alone; now you can't do your side-by-side comparison.

Hopefully that helps illustrate the pain. There are ways to work around this, but it would be ideal if we could just "set and forget" a vite option if we want to be in control of when our pages reload.

rmacklin avatar May 04 '24 01:05 rmacklin