Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React-Hot-Loader: react-🔥-dom patch is not detected. React 16.6+ features may not work. #1227

Closed
rybon opened this issue Apr 11, 2019 · 58 comments

Comments

@rybon
Copy link

rybon commented Apr 11, 2019

What is the actionable thing to do here? I've followed the required steps to set it up, but still see this warning.

@rybon rybon changed the title eact-Hot-Loader: react-🔥-dom patch is not detected. React 16.6+ features may not work. React-Hot-Loader: react-🔥-dom patch is not detected. React 16.6+ features may not work. Apr 11, 2019
@HashemKhalifa
Copy link

HashemKhalifa commented Apr 11, 2019

you need to add the matched version for react-hot-dom in your package file

"@hot-loader/react-dom": "^16.8.6",

and in your webpack config, you need to add

 alias: { 'react-dom': '@hot-loader/react-dom'  }

@rybon
Copy link
Author

rybon commented Apr 11, 2019

Okay, that indeed resolves the issue. But shouldn't that be added as a step 4? The readme is confusing about this. It says a Webpack plugin is required, then recommends using the Babel plugin instead. The Webpack plugin apparently patches React DOM for you to basically turn it into @hot-loader/react-dom, but it is unclear if it can be used in conjunction with the Babel plugin. Can both plugins be used at the same time or will that lead to conflicts or other downsides?

@rybon
Copy link
Author

rybon commented Apr 11, 2019

Using the Webpack plugin in conjunction with the Babel plugin does not remove the warning. Solely using the Webpack plugin doesn't either. Only the Babel plugin combined with @hot-loader/react-dom and a Webpack config alias does.

@Macil
Copy link

Macil commented Apr 11, 2019

For me, just using the webpack plugin (with include: /node_modules/ so it only runs on node_modules(?) -- maybe you're missing this part?) and the babel plugin together seems to make everything work correctly, including making that warning go away.

I'm also really confused by the readme. I'm slightly worried that I might have things set up incorrectly and only working by coincidence and that it might break on an update.

@rybon
Copy link
Author

rybon commented Apr 11, 2019

I probably forgot include: /node_modules/ for the Webpack plugin. Will try that.

@theKashey
Copy link
Collaborator

Usually, it's not about include, but exclude.
There are 3 ways to set up "hot-patch", and webpack-loader is working only for webpack, while it's not the only one bundler one could use.

PS: Feel free to change README to be more clear and understandable.

@rybon
Copy link
Author

rybon commented Apr 11, 2019

The Webpack plugin with include: /node_modules/ indeed does the trick. @hot-loader/react-dom and the Webpack config is alias is no longer required in that case.

@theKashey is it okay to use the Babel and Webpack plugins at the same time? Or are they meant to be used separately?

@theKashey
Copy link
Collaborator

That's ok, they are taught to be friends :)
They were not before webpack-loader got ability to patch react-dom and probably some pieces of that past are still among readme.

@HashemKhalifa
Copy link

@rybon would you kindly share the config with us?

@rybon
Copy link
Author

rybon commented Apr 12, 2019

Sure.

// App.jsx

import { hot } from 'react-hot-loader/root'

// ...

export default hot(App)
// .babelrc

{
  "plugins": ["react-hot-loader/babel"]
  // ...
}
// package.json

{
  "dependencies": {
    "react-hot-loader": "^4.8.3",
    "@hot-loader/react-dom": "^16.8.6"
    // ...
  }
  // ...
}
// webpack.config.js

{
  // ...
  resolve: {
    alias: {
      'react-dom': '@hot-loader/react-dom'
    }
  }
}

@rybon
Copy link
Author

rybon commented Apr 12, 2019

Alternative:

// App.jsx

import { hot } from 'react-hot-loader/root'

// ...

export default hot(App)
// package.json

{
  "dependencies": {
    "react-hot-loader": "^4.8.3"
    // ...
  }
  // ...
}
// webpack.config.js

{
  // ...
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
        include: /src/
      },
      {
        test: /\.(js|jsx)$/,
        use: 'react-hot-loader/webpack',
        include: /node_modules/
      }
      // ...
  ]
}

Notice:

  • no .babelrc change required
  • no @hot-loader/react-dom required
  • no Webpack config resolve.alias required

@rybon
Copy link
Author

rybon commented Apr 12, 2019

Now the question is, which configuration is preferable? What are the downsides of the alternative configuration? That is not clear to me. Personally, I prefer the alternative configuration, because it requires less configuration. But if it does not work as properly as the Babel approach, I'd rather use that.
When using the Webpack approach, should the .babelrc plugin be used as well? Or can it safely be omitted?

@HashemKhalifa
Copy link

@rybon I agree with you it's quite confusing for me as well and the first approach doesn't work as expected because of react-dom alias. and the babel approach working perfectly fine for me.

btw you can use babel-config.js instead of .babelrc if you are using babel 7

@rybon
Copy link
Author

rybon commented Apr 12, 2019

Okay. I just noticed when using the Webpack approach without @hot-loader/react-dom that in some cases the HMR only works the first time, but not in subsequent times. Adding the .babelrc / babel-config.js plugin back in resolves that issue.

So, I guess the recommendation would be to always use the Babel plugin? And then decide to go with either the Webpack plugin or the @hot-loader/react-dom and the Webpack resolve.alias setting.

@theKashey
Copy link
Collaborator

You have to use babel-plugin or webpack-loader to make RHL work. @hot-loader/react-dom in any form - is just an addition.

@milanvdm
Copy link

milanvdm commented Apr 13, 2019

How would you set this up using Parcel?
Because I have the babel-plugin but still see this warning.

@kpopovic
Copy link

Hello,
a get this message

"React-Hot-Loader: react-🔥-dom patch is not detected. React 16.6+ features may not work" when using https://parceljs.org/ bundler. Can this message be fixed for https://parceljs.org/ ?

This is how I tried to load App (using Hooks):

import { hot } from 'react-hot-loader'
import React from 'react'
...
export default hot(module)(App)

is there any working example using Parcel + React Hooks ?

Best Regards,
Krešimir

@theKashey
Copy link
Collaborator

For parcel use hot-loader/react-dom

Use alias field in package.json to rewire your project. This will affect dev and production modes. See parcel-bundler/parcel#850
{
"alias": {
"react-dom": "@hot-loader/react-dom"
}
}

@kpopovic
Copy link

Hello @theKashey ,
now it is fine. No WARN message shown.

how I start the web app:
NODE_ENV=development parcel -p 3500 assets/index.html --open

package.json snippet:
...
"alias": {
"react-dom": "@hot-loader/react-dom"
},
....

@karlitos
Copy link

karlitos commented May 14, 2019

Hi, I suffer from the same warning as other. I do not use webpack, I work on a electron app which utilizes the electron-compile.

If I use yarn (yarn add react-dom@npm:@hot-loader/react-dom) I do net get the warning, but it adds

"react-dom": "npm:@hot-loader/react-dom",

to my package.json which is something npm is not compatible with.

npm ERR! code EUNSUPPORTEDPROTOCOL npm ERR! Unsupported URL Type "npm:": npm:@hot-loader/react-do

I would like to stick with npm instead of yarn, but I am not able to get rid of the warning with my setup:

"dependencies": {
    "@hot-loader/react-dom": "^16.8.6",
    "electron-compile": "^6.4.4",
    "electron-devtools-installer": "^2.1.0",
    "electron-squirrel-startup": "^1.0.0",
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "react-hot-loader": "^v4.8.4"
  },
  "devDependencies": {
    "babel-plugin-transform-async-to-generator": "^6.24.1",
    "babel-plugin-transform-es2015-classes": "^6.24.1",
    "babel-preset-env": "^1.7.0",
    "babel-preset-react": "^6.24.1",
    "electron-forge": "^5.2.4",
    "electron-prebuilt-compile": "4.0.0",
    "eslint": "^3",
    "eslint-config-airbnb": "^15",
    "eslint-plugin-import": "^2",
    "eslint-plugin-jsx-a11y": "^5",
    "eslint-plugin-react": "^7"
  },
  "alias": {
    "react-dom": "@hot-loader/react-dom"
  }

It says, that .compilerc (the electron-compile config) also accepts environments with the same syntax as .babelrc. My .compilerc looks like:

{
  "env": {
    "development": {
      "application/javascript": {
        "presets": [
          ["env", { "targets": { "electron": "1.6.0" } }],
          "react"
        ],
        "plugins": ["transform-async-to-generator", "transform-es2015-classes", "react-hot-loader/babel"],
        "sourceMaps": "inline"
      }
    },
    "production": {
      "application/javascript": {
        "presets": [
          ["env", { "targets": { "electron": "1.6.0" } }],
          "react"
        ],
        "plugins": ["transform-async-to-generator", "transform-es2015-classes"],
        "sourceMaps": "none"
      }
    }
  }
}

I tried to add the es2017-node7 babel, preset, but still no luck.

I also tried to use babel-plugin-module-resolver and changed the development section of my .compilerc to:

...
"plugins": ["transform-async-to-generator", "transform-es2015-classes", "react-hot-loader/babel",
        ["module-resolver", {
              "alias": {
                 "react-dom": "@hot-loader/react-dom"
              }
            }]
        ],
...

Still no luck 😢

Is there a way to get react-hot-reload to work without needing to use yarn ?

@theKashey
Copy link
Collaborator

You can always “ln” real directories.

@karlitos
Copy link

You can always “ln” real directories.

Thank you, I tried this already and it works. But this approach makes a local development setup quite difficult. 🤕

The issue with react-🔥-dom not being used properly is caused by babel-plugin-module-resolver and the fact babel is ignoring node_modules by default.

The electron-compile project is marked as deprecated by now, so there won't be probably any support for setting aliases for npm modules in the future.

I tried a different approach with setting an environment variable in the script for the local development and using the right ReactDOM respectively:

import 'react-hot-loader';
import React from 'react';
import ReactDOM from 'react-dom';
import PatchedReactDOM from '@hot-loader/react-dom';
import App from './components/App';

if (process.env.REACT_DOM === 'patched') {
  PatchedReactDOM.render(<App />, document.getElementById('App'));
} else {
  ReactDOM.render(<App />, document.getElementById('App'));
}

but although the if-else is being resolved properly, I still get the warning.

@theKashey
Copy link
Collaborator

theKashey commented May 15, 2019

Not, it would not work exactly this way - by default RHL would patch something names react-dom. You might patch another thing, calling ReactHotLoader.patch(React, PatchedReactDOM); manually, but it would not remove the message.

Probably the best option is to move this message from configure time to a render time(AppContainer constructor), giving you options to suppress or fix it.

@theKashey
Copy link
Collaborator

Try update RHL to the latest 4.12.14 version (leased early this week) - it shall address this problem.

ninjaPixel added a commit to ninjaPixel/meteor-boilerplate that referenced this issue Nov 15, 2019
HMR breaks when using @hot-loader/react-dom

I tried the fix from here: gaearon/react-hot-loader#1227 (comment)

But HMR just stopped working properly - e.g chaning text i na Typgraph component would trigger a rebuild, but the web page would not update with the new text.
@jeanlescure
Copy link

Just in case you arrive here while using neutrinojs, here's my webpack.config.js file:

const neutrino = require('neutrino');
const webpack = require('webpack');
const dotenv = require('dotenv');

const env = dotenv.config().parsed;

const envKeys = Object.keys(env).reduce((prev, next) => {
  prev[`process.env.${next}`] = JSON.stringify(env[next]);
  return prev;
}, {});

const config = neutrino().webpack();

const pluginConfig = {
  plugins: [
    ...config.plugins,
    new webpack.DefinePlugin(envKeys)
  ]
};

const aliasConfig = {
  resolve: {
    ...config.resolve,
    alias: {
      ...config.resolve.alias,
      'react-dom': '@hot-loader/react-dom'
    }
  }
};

if (process.env.ENVIRONMENT !== 'production') {
  module.exports = {
    ...config,
    ...pluginConfig,
    ...aliasConfig
  };
} else {
  module.exports = {
    ...config,
    ...pluginConfig
  };
}

Based on all previous discussion it seemed pretty straight forward to just inject the alias into neutrino's config.

Hope someone finds this to be useful 🚀

@jeremy-ww
Copy link

@lili21 I guess it's a feature belongs to webpack, maybe webpack externals have higher priority than an alias. So u can revise your webpack.config.js as below:

webpack.base.js

externals: {
  react: 'React',
  'react-router-dom': 'ReactRouterDOM'
}

webpack.development.js

resolve: {
  alias: { 'react-dom': '@hot-loader/react-dom' }
}

webpack.production.js

externals: {
  'react-dom': 'ReactDOM'
}

@soulcm
Copy link

soulcm commented Feb 12, 2020

Doesn't work If I'm using webpack externals.

// webpack.config.js
...
externals: {
  'react-dom': 'ReactDOM'
}
...

I have the same problems

@theKashey
Copy link
Collaborator

More or less expected. However, why do you need it as external in dev mode?

@merveillevaneck
Copy link

merveillevaneck commented Feb 12, 2020

Soooo like literally the docs resolved this issue for anyone still running into the console warning:

yarn add react-dom@npm:@hot-loader/react-dom

installs the hot-loader patch and links it for use without having to eject anything. so win-win :)

Thanks React Team

tangrammer added a commit to akvo/akvo-lumen that referenced this issue Feb 18, 2020
zburke added a commit to folio-org/stripes-core that referenced this issue Mar 16, 2020
In local development, the console would report the following error:
```
07:28:59.865 react-hot-loader.development.js:2375 React-Hot-Loader: react-🔥-dom patch is not detected. React 16.6+ features may not work.
    AppContainer @ react-hot-loader.development.js:2375
    AppContainer @ VM2755:14
    constructClassInstance @ react-dom.development.js:14204
    updateClassComponent @ react-dom.development.js:18413
    beginWork$1 @ react-dom.development.js:20186
    beginWork$$1 @ react-dom.development.js:25756
...
```
That leads to gaearon/react-hot-loader#1227
where it is noted over a series of comments that the configuration
instrucations are rather confusing:
> The readme is confusing about this. It says a Webpack plugin is required, then recommends using the Babel plugin instead. The Webpack plugin apparently patches React DOM for you to basically turn it into @hot-loader/react-dom, but it is unclear if it can be used in conjunction with the Babel plugin.
> ...
> Using the Webpack plugin in conjunction with the Babel plugin does not remove the warning. Solely using the Webpack plugin doesn't either. Only the Babel plugin combined with `@hot-loader/react-dom` and a Webpack config alias does.

And eventually leads to the following "this config seems to work":
```
// App.jsx

import { hot } from 'react-hot-loader/root'

// ...

export default hot(App)
```

```
// .babelrc

{
  "plugins": ["react-hot-loader/babel"]
  // ...
}
```

```
// package.json

{
  "dependencies": {
    "react-hot-loader": "^4.8.3",
    "@hot-loader/react-dom": "^16.8.6"
    // ...
  }
  // ...
}
```

```
// webpack.config.js

{
  // ...
  resolve: {
    alias: {
      'react-dom': '@hot-loader/react-dom'
    }
  }
}
```
zburke added a commit to folio-org/stripes-core that referenced this issue Mar 16, 2020
In local development, the console would report the following error:
```
07:28:59.865 react-hot-loader.development.js:2375 React-Hot-Loader: react-🔥-dom patch is not detected. React 16.6+ features may not work.
    AppContainer @ react-hot-loader.development.js:2375
    AppContainer @ VM2755:14
    constructClassInstance @ react-dom.development.js:14204
    updateClassComponent @ react-dom.development.js:18413
    beginWork$1 @ react-dom.development.js:20186
    beginWork$$1 @ react-dom.development.js:25756
...
```
That leads to gaearon/react-hot-loader#1227
where it is noted over a series of comments that the configuration
instrucations are rather confusing:
> The readme is confusing about this. It says a Webpack plugin is required, then recommends using the Babel plugin instead. The Webpack plugin apparently patches React DOM for you to basically turn it into @hot-loader/react-dom, but it is unclear if it can be used in conjunction with the Babel plugin.
> ...
> Using the Webpack plugin in conjunction with the Babel plugin does not remove the warning. Solely using the Webpack plugin doesn't either. Only the Babel plugin combined with `@hot-loader/react-dom` and a Webpack config alias does.

And eventually leads to the following "this config seems to work":
```
// App.jsx

import { hot } from 'react-hot-loader/root'

// ...

export default hot(App)
```

```
// .babelrc

{
  "plugins": ["react-hot-loader/babel"]
  // ...
}
```

```
// package.json

{
  "dependencies": {
    "react-hot-loader": "^4.8.3",
    "@hot-loader/react-dom": "^16.8.6"
    // ...
  }
  // ...
}
```

```
// webpack.config.js

{
  // ...
  resolve: {
    alias: {
      'react-dom': '@hot-loader/react-dom'
    }
  }
}
```
@CaptainWild
Copy link

CaptainWild commented Jul 11, 2020

I have got the same issue and tried to resolve it according to these guide here, but got same error message.
Pls reach me out and help me.
Thank you.

@an-ivannikov
Copy link

It Worked For Expo Web App.
File webpack.config.js

const createExpoWebpackConfigAsync = require('@expo/webpack-config');

module.exports = async function (env, argv) {
  const config = await createExpoWebpackConfigAsync(env, argv);
  // Customize the config before returning it.
  config.resolve.alias['react-dom'] = '@hot-loader/react-dom';
  return config;
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests