Search code examples
reactjswebpack-hmrreact-hot-loader

How could the NODE_ENV check cause the hot loading to be a page refreshing?


Recently I have a project setup for Hot module reloading, I use this script to start dev via webpack-dev-server:

"NODE_ENV=development ./node_modules/.bin/webpack-dev-server --progress --config webpack.dev.js"

The hot module reloading works. Until I change

if (module.hot) {
    module.hot.accept('./components/App', () => {
        renderWrapper(App);
    });
}

to

if (process.env.NODE_ENV === 'development'){
    // Original HMR code
}

Then every time I change something, it became a full page reloading. I found the following log in the console of Chrome:

[HMR] Cannot apply update. Need to do a full reload!

[HMR] Error: Aborted because ./client/containers/SearchBox.jsx is not accepted

Update propagation:
./client/containers/SearchBox.jsx
-> ./client/components/HomePage.jsx
-> ./client/components/App/index.jsx
-> ./client/index.jsx

Why?

If I don't do that development check, everything works.

Furthermore, do I need to check that for doing HMR? If I create the production build without taking out the HMR block, will it cause a problem?


Solution

  • If you do console.log(process.env.NODE_ENV) right before your condition you will probably get undefined. That is why your app can't catch module updates.

    The thing is that you set NODE_ENV=development for nodejs's environment, but not for webpack's. In your webpack.config.js add the following plugin to plugins list:

    new webpack.DefinePlugin({
      process: {
        env: {
          NODE_ENV: JSON.stringify(process.env.NODE_ENV || 'development')
        }
      }
    })
    

    This will tell webpack to replace process.env.NODE_ENV in your client code to the appropriate value. Don't forget to wrap it in JSON.stringify as in example above. See this doc link for details.