Next.js: Disable HMR

Created on 13 Feb 2017  ·  34Comments  ·  Source: vercel/next.js

I wonder how could I disable HMR when I run yarn dev.

Most helpful comment

After 2 years of people complaining about HMR there is still no official way to disable it ?!!

All 34 comments

HMR is always supported in the dev mode. There's no official way to turn it off.
We have no plans to do it in the short term.

Wouldn't this cause a load on the server, we need a way to turn HMR off for running in production.

It's off in production. Make sure you're running next build and next start or next build and NODE_ENV=production node server.js in production.

Turning HMR off can be useful when working on the layout. I'm editing styled-components and some global css styles, but the preview gets broken pretty soon. The reason is that the page gets a mix of SSR-rendered styles and the just generated ones. There seems to be no way to overcome this except by switching HMR off.

In addition to HMR still being compatible only with ES5 (not everybody needs to transpile classes anymore), I’ve been regularly encountering spazzy HMR-related bugs that occur only in development. I would really love to have a way to disable it.

Even a hacky solution would be appreciated. It’s turning into a nightmare.

I believe I'm encountering a related issue. Currently trying to use react-waypoint in a Next.js page. When calling this.setState from within a Waypoint event handler I'm getting a Maximum call stack size exceeded error. This only occurs when running Next.js in dev mode. If I npm run build and npm start the issue does not occur.

Maybe related to this issue?

Any way we could reopen this issue. HMR can be very annoying in multiple situations. If this is not a priority, can you provide some info of where to find that code (to manually disable it) and/or make a PR @arunoda

Right now we are experiencing huge problems with Apollo GraphQL + Next JS (5.0.0). getDataFromTree just don't work and this breaks many things in our setup :(

@timneutkens, @arunoda, can you reopen this?

And by the way https://github.com/zeit/next.js/issues/1938#issuecomment-358195616

looks like an issue with shouldComponentUpdate. Important thing to know is that in dev mode these functions aren't called because of limitations of the hot reloading functionality.
I'd say run in production mode locally and add some logging to your functions.

This seems like a major thing

Sometimes I would like to disable HMR in dev mode just to avoid cluttering the dev tools network tab with un-needed message noise.

"on-demand-entries-ping?page=/xxx", etc

Pressing CMD-R to reload the page is no big problem, restarting the server to get updates in prod mode is a pain.

as a workaround, you can prevent hmr requests with chrome dev tools "Request blocking" feature

screen shot 2018-06-08 at 14 58 25

@vanmik Great tip, thanks! ✨

To find Request Blocking in Chrome (66 at least) you may need to:

open 'Customize and control DevTools' (three vertical dots) > More tools > Request Blocking. This will open the Request Blocking console where you can check the request sources to block, as shown in @vanmik's screen shot.

Want to mention you're not limited to dev tools with that. You can use a browser plugin to block requests. In this case you don't need to keep dev tools opened every time just for that.

But I hope in the future we would get something simple as:

// next.config.js
module.exports = {
  hmr: false
}

HRM sucks. It brings difficulties more often than benefits (e.g. when some parts of the code get hot-reloaded while some don't which causes an inconsistent state).

While @vanmik's tip stops the actual HMR operation, my dev console is still cluttered with http://localhost:3000/_next/on-demand-entries-ping?page=/xxx entries, only now they are errors.

Not acceptable for debugging :-/

Sure would love to have

// next.config.js
module.exports = {
  hmr: false
}

Maybe someone could write a plugin for this ???

@gihrig you can filter these errors with console context menu (rightclick on the error):

screen shot 2018-08-21 at 12 35 07

@arunoda Any progress on this? I'm having an issue with HMR and immutablejs proptypes - super frustrating. See: https://github.com/facebook/prop-types/issues/221

My workaround for it was to enable request blocking and then add the on-demand-entries-ping request to the list of blocked requests. Hope it helps others who dislike HMR as much as I do.


screen shot 2018-11-27 at 3 07 14 pm


screen shot 2018-11-27 at 3 07 50 pm

To disable Hot Module Reloading (HMR) in Next.js v7+, add this to your next.config.js file:

module.exports = {
  webpackDevMiddleware: (config) => {
    config.watchOptions = config.watchOptions || {};
    config.watchOptions.ignored = [
      // Don't watch _any_ files for changes
      /.*/,
    ];
    return config;
  },
};

This will disable rebuilding on change, which in turn will cause the browser to never "see" any changes, and hence will not reload anything. This means Next.js will not recompile on changes. You will have to restart the next.js server every time there's a change, then refresh your browser.

For a solution which forces en entire page reload on each change, see this comment below.

For a solution which will always reload the page on changes, you can create a server.js:

const next = require('next')

const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

app.prepare().then(() => {

  // ℹ️ Below is the magic which forces a page reload on every change
  // ℹ️ From https://github.com/zeit/next.js/issues/1109#issuecomment-446841487

  // The publish function tells the client when there's a change that should be hot reloaded
  const publish = app.hotReloader.webpackHotMiddleware.publish.bind(
    app.hotReloader.webpackHotMiddleware,
  );

  // Intercept publish events so we can send something custom
  app.hotReloader.webpackHotMiddleware.publish = (event, ...rest) => {
    let forwardedEvent = event;

    // upgrade from a "change" to a "reload" event to trick the browser into reloading
    if (event.action === 'change') {
      forwardedEvent = {
        action: 'reload',
        // Only `/_document` pages will trigger a full browser refresh, so we force it here.
        data: ['/_document'],
      };
    }

    // Forward the (original or upgraded) event on to the browser
    publish(forwardedEvent, ...rest);
  };
  // ℹ️ End force page reload on change

  // ... Whatever custom server setup you have. See: https://github.com/zeit/next.js/#custom-server-and-routing
});

I'm like 80% sure this will break in the future.

It's a horrible hack, but the only way I was able to work around a bug which would cause the browser tab to consume >100% CPU then crash in Chrome on every hot reload.

Hopefully by the time the hack breaks, there'll be an official solution or the bugs mentioned in this issue will be fixed 👍

The reason I want to disable HMR is that the DevTools/Applications/Cookies (Chrome Windows) panel loses focus as you type in it because the HMR updates keep happening in the background. I suspect that this would be the case even if I told webpackDevServer to ignore all files. The websocket connection would still be made in the background and I believe that it is this connection that's thrashing the cookies panel.

Point being: an ideal solution must disable HMR entirely. Thanks!

It is unfortunate you can't just add this to your next.config.js

module.exports = {
  webpackDevMiddleware: config => {
    config.lazy = true;
    return config;
  },
};

This option instructs the module to operate in 'lazy' mode, meaning that it won't recompile when files change, but rather on each request. Sounds like something a lot of us are hoping for without having to go as far as @jesstelford's solutions.

Source: https://github.com/webpack/webpack-dev-middleware#lazy

When I try this on next 7.0.2, I get the following error:

screen shot 2018-12-25 at 12 58 18 am

Had an opportunity to work with a Create React App project today.

I think the root of this HMR problem is not that HMR is evil so much as the way it's implemented.

Simply put, having the client periodically polling the server is less than ideal.

From a cursory observation it appears that CRA uses a socket connection that only communicates to the client when a file has changed, then the client reloads the page. This scheme also results in a faster browser refresh because the operation is not dependent on the next polling interval.

CRA is open source. It would be great if someone with the time and interest could dig into upgrading Next's HMR to follow the CRA model (and make it easily disabled as well, of course :-)

@gihrig there are probably a few different reasons why people are looking to disable HMR.

My understanding is that react-hot-loader requires certain assumptions to hold about how your application is written, how state is modeled, and the absence of significant object identity. These assumptions typically hold for a correctly written redux-based app, but may not hold for apps that have been designed using other approaches. I agree that the issue isn’t that HMR is evil — it’s just that it’s not a generic tool. This creates some dissonance in the context of a framework that is otherwise agnostic about these design decisions.

Switching from polling to websockets is probably a good idea, but polling isn’t “the root of the problem,” or rather it’s unrelated to at least some of the problems people here have run into.

Note that both the last 2 comments make wrong assumptions:

  • Next.js doesn’t use react-hot-loader, it re-renders the component tree when a change is emitted
  • Next.js doesn’t do polling to receive changes, it does polling to mark which pages are still being viewed, on canary this has been changed to a websocket just so that the user doesn’t see the polling happening in their devtools. To further expand on this HMR works using an event source connection, meaning the server sends events (on file change) to the browser

@timneutkens That’s great to hear, thanks. It wasn’t a wrong assumption, though, it was outdated info. RHL was in use when we started using Next and it was the cause of the problems we encountered that led me to originally comment in this thread. I haven’t seen any issues related to HMR when using Next in a while now, though.

In fact, we’re now able to run our ES2017 build in dev!

After 2 years of people complaining about HMR there is still no official way to disable it ?!!

Why is this loggin GET /_next/on-demand-entries-ping?page=/ on my NON next.js app?

-- self-resolved: had to comment out the logger app.use.(morgan(dev)) the strange thing is that Morgan is installed on a different app with no next.js, so something is going on with this being logged by Morgan, I want to know why is this happening. This was not happening before installing next.js on a different project.

Please reopen the issue is definitly not solved.

+1

Was this page helpful?
0 / 5 - 0 ratings

Related issues

timneutkens picture timneutkens  ·  3Comments

havefive picture havefive  ·  3Comments

lixiaoyan picture lixiaoyan  ·  3Comments

swrdfish picture swrdfish  ·  3Comments

wagerfield picture wagerfield  ·  3Comments