React-hot-loader: Webpack 2 way doesn't work

Created on 12 May 2017  路  11Comments  路  Source: gaearon/react-hot-loader

https://github.com/gaearon/react-hot-loader/tree/master/docs#webpack-2

You said here I can do this:

if (module.hot) {
  module.hot.accept('./App', () => {
    // const NextApp = require('./App').default
    // render(NextApp)
    render(App)
  })
}

You also specified that we have to disable module to be able to do this, so I split my babel configuration to have one for starting webpack, and one for compiling my code.

So i've got this:

// webpack.babel.js
import babelConfig from './babel.config.js'

{
          test: /\.jsx?$/,
          exclude: /node_modules/,
          loader: 'babel-loader',
          options: babelConfig,
},

// .babelrc
{
  "presets": [
    "es2015"
  ]
}

// babel.config.js
export default {
  "presets": [
    ["env", { "modules": false }],
    "react"
  ],
  "plugins": [
    "react-hot-loader/babel",
    "transform-class-properties",
    "transform-object-rest-spread"
  ],
}

But it doesn't refresh anything.

If I do:

if (module.hot) {
  module.hot.accept('./App', () => {
    const NextApp = require('./App').default
    render(NextApp)
  })
}

it works.

Do you have any idea why?

I wanted to do this because I was trying to make myFunct = () => {} in a react class work.

Most helpful comment

Hi, I also had a similar issue. In my case I was using the babel-preset-latest, but I think it will be the same thing for the env preset. Originally I had this in my babelrc:

"presets": [
  ["latest", {
    "modules": false
  }]
]

which did not work, because the options are not passed to individual "subpresets". I had to replace it with this to make it work.

"presets": [
  ["latest", {
    "es2015": {
      "modules": false
    }
  }]
]

Since I am not the only one to run into this issue, it might be worth mentioning it in the webpack2 note in the migration guide :)

All 11 comments

I ran into a similar issue awhile ago and I think it had something to do with a babel transform. I would suggest disabling transform-class-properties and seeing if that fixes it.

I think it might be because of the order of your babel plugins. Try to move the react-hot-loader last in the array.

export default {
  "presets": [
    ["env", { "modules": false }],
    "react"
  ],
  "plugins": [
    "transform-class-properties",
    "transform-object-rest-spread",
    "react-hot-loader/babel"
  ],
}

I have a similar setup and that works for me, although all of my babel config is inside .babelrc 馃槃

Hi, I also had a similar issue. In my case I was using the babel-preset-latest, but I think it will be the same thing for the env preset. Originally I had this in my babelrc:

"presets": [
  ["latest", {
    "modules": false
  }]
]

which did not work, because the options are not passed to individual "subpresets". I had to replace it with this to make it work.

"presets": [
  ["latest", {
    "es2015": {
      "modules": false
    }
  }]
]

Since I am not the only one to run into this issue, it might be worth mentioning it in the webpack2 note in the migration guide :)

Neither

export default {
  "presets": [
    ["env", {
      "es2015": {
        "modules": false
      }
    }],
    "react"
  ],
  "plugins": [
    ["import", { "libraryName": "antd" }],
    "transform-class-properties",
    "transform-object-rest-spread",
    "react-hot-loader/babel",
  ],
}

nor

export default {
  "presets": [
    ["env", { "modules": false }],
    "react"
  ],
  "plugins": [
    ["import", { "libraryName": "antd" }],
    "transform-class-properties",
    "transform-object-rest-spread",
    "react-hot-loader/babel",
  ],
}

work here with

if (module.hot) {
  module.hot.accept('./App', () => {
    // const NextApp = require('./App').default
    // render(NextApp)
    render(App)
  })
}

I can confirm that setting ['env', {'modules': false }] solves the issue.

@kud you need to remove the duplication of presets settings in your .babelrc/babel.config.js, that should solve the issue for you.

//.babelrc
{
  "presets": [
    ["es2015", { "modules": false }],
    "stage-0",
    "react"],
  "plugins": ["react-hot-loader/babel"]
}

// webpack.config.js
...
module: {
    rules: [{
      test: /\.js$/,
      use: ['babel-loader']
    }]
  }
...

// index.js
import React from 'react'
import ReactDOM from 'react-dom'
import { AppContainer } from 'react-hot-loader'

import App from './App'

const render = Component => {
  ReactDOM.render(
    <AppContainer>
      <Component />
    </AppContainer>,
    document.getElementById('app')
  )
}

render(App)

if (module.hot) {
  module.hot.accept('./App', () => { render(App) })
}

worked for me

"react-hot-loader": "next",
"webpack": "^3.0.0"

add option babelrc: false to your babel.config.js to disable the .babelrc file in your root folder

I've managed to work this only when fixed this three things:

  • No .babelrc in root folder or babelrc: false in options for babel-loader
  • Correct place for 'modules': false is:
    'presets': [
        ['env', {
            'modules': false,
                 'targets': { ... }
            }]
    ]
  • react-hot-loader/babel plugin is placed after all other plugins in the list of plugins for babel-loader options.

Sounds fixed.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Opty1712 picture Opty1712  路  4Comments

calvinchankf picture calvinchankf  路  3Comments

rockchalkwushock picture rockchalkwushock  路  3Comments

zlk89 picture zlk89  路  3Comments

lemonmade picture lemonmade  路  3Comments