Search code examples
javascripthtmlwebpackwebpack-dev-serveronbeforeunload

How do I configure webpack-dev-server to turn off "beforeunload" events on the browser before reload?


My form pages have a beforeunload event/function set on the window to warn the user to save their changes before moving on to a different page or refreshing. It works great, and looks something like this:

$(window).on("beforeunload", myCustomWindowBeforeUnloadFunction);

The problem is when running in development, every time I change a file in my IDE, Webpack Dev Server attempts to auto-reload the page. I want to turn off this beforeunload event so I don't keep getting nagged with this alert in Chrome:

Are you sure you want to leave the page? Data you have entered may not be saved.

Is there a way I can run a custom function in the browser before Webpack Dev Server attempts to reload the page?


Solution

  • Maybe something like this:

    if (process.env.DEV) {
      window.addEventListener('message', ({ data: { type } }) => {
        if (type === 'webpackInvalid') {
          $(window).off('beforeunload');
        } else if (type === 'INIT_INSTANCE') {
          $(window).on('beforeunload', myCustomWindowBeforeUnloadFunction);
        }
      });
    }
    

    I've added process.env.DEV with EnvironmentPlugin to make sure that code doesn't make it to production. You could also use process.env.NODE_ENV === 'development', which works without adding EnvironmentPlugin, as Webpack adds that automatically.

    Or, using HMR's addStatusHandler function:

    if (process.env.DEV && module.hot) {
      module.hot.accept();
    
      module.hot.addStatusHandler((status) => {
        if (status === 'prepare') {
          $(window).off('beforeunload');
        } else if (/apply|abort|fail/.test(status)) {
          $(window).on('beforeunload', myCustomWindowBeforeUnloadFunction);
        }
      });
    }
    

    Note module.hot will be there if you are using HotModuleReplacementPlugin, no need to import that, as explained here:

    If Hot Module Replacement has been enabled via the HotModuleReplacementPlugin, its interface will be exposed under the module.hot property. Typically, users will check to see if the interface is accessible, then begin working with it.

    Also, maybe instead of checking for apply, abort or fail in the second condition, you could use idle.