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

fix(gatsby): show @hot-loader installation prompt #26927

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions dictionary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,7 @@ Dodds
Doggo
DOM
DOMPurify
dom
doopoll
dotenv
doubleBind
Expand Down Expand Up @@ -964,6 +965,7 @@ Hexo
hinzufügen
HIPAA
Hmmm
HMR
HOC
HOCs
Holík
Expand Down
24 changes: 24 additions & 0 deletions docs/docs/troubleshooting-common-errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -256,3 +256,27 @@ echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo s
```

You may be able to find more information for your circumstances in [the GitHub issue corresponding to this error](https://github.com/gatsbyjs/gatsby/issues/11406).

## Errors during development

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

`gatsby develop` uses Hot Module Replacement (HMR) to update your webpage without refreshing the page. The package that Gatsby uses for HMR is [react-hot-loader](https://github.com/gaearon/react-hot-loader). When opening the console, you might see the following warning:

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

To make sure all React features work, you'll have to install `@hot-loader/react-dom`. It's a patched version of the original `react-dom` package that makes [React Hooks](https://reactjs.org/docs/hooks-intro.html) work with HMR. When not available, changes made in a file that contains a React hook will do a forced browser refresh instead of a hot module update.

You have to make sure the installed version of `@hot-loader/react-dom` is the same as your `react-dom` version. For example, if `react-dom` is at version 16.13.0, you'll have to install `@hot-loader/[email protected]`. In this case, you would see the following message in your CLI:

```shell
warning React-Hot-Loader: please install "@hot-loader/[email protected]" to make sure all features of React are working.
```

To resolve this message, install the matching version of `@hot-loader/react-dom` using `npm install` (or its Yarn equivalent, `yarn add`):

```shell
npm install @hot-loader/[email protected]
```
10 changes: 0 additions & 10 deletions packages/gatsby/src/utils/webpack-hmr-hooks-patch.js

This file was deleted.

41 changes: 27 additions & 14 deletions packages/gatsby/src/utils/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const apiRunnerNode = require(`./api-runner-node`)
import { createWebpackUtils } from "./webpack-utils"
import { hasLocalEslint } from "./local-eslint-config-finder"
import { getAbsolutePathForVirtualModule } from "./gatsby-webpack-virtual-modules"
import semver from "semver"

const FRAMEWORK_BUNDLES = [`react`, `react-dom`, `scheduler`, `prop-types`]

Expand Down Expand Up @@ -164,11 +165,14 @@ module.exports = async (
return {
polyfill: directoryPath(`.cache/polyfill-entry`),
commons: [
process.env.GATSBY_HOT_LOADER === `fast-refresh`
? `react-hot-loader/patch`
: null,
`${require.resolve(
`webpack-hot-middleware/client`
)}?path=${getHmrPath()}`,
directoryPath(`.cache/app`),
],
].filter(Boolean),
}
case `develop-html`:
return {
Expand Down Expand Up @@ -324,19 +328,6 @@ module.exports = async (
},
])

// RHL will patch React, replace React-DOM by React-🔥-DOM and work with fiber directly
// It's necessary to remove the warning in console (https://github.com/gatsbyjs/gatsby/issues/11934)
// TODO: Remove entire block when we make fast-refresh the default
if (process.env.GATSBY_HOT_LOADER !== `fast-refresh`) {
configRules.push({
include: /node_modules\/react-dom/,
test: /\.jsx?$/,
use: {
loader: require.resolve(`./webpack-hmr-hooks-patch`),
},
})
}

break
}
case `build-html`:
Expand Down Expand Up @@ -423,6 +414,28 @@ module.exports = async (
],
}

// if react-hot-reloading
if (
stage === `develop` &&
process.env.GATSBY_HOT_LOADER !== `fast-refresh`
) {
resolve.alias[`react-hot-loader`] = path.dirname(
require.resolve(`react-hot-loader/package.json`)
)

// We need to add @hot-loader/react-dom to support hot-loader work with hooks
try {
resolve.alias[`react-dom/server$`] = require.resolve(`react-dom/server`)
resolve.alias[`react-dom`] = require.resolve(`@hot-loader/react-dom`)
wardpeet marked this conversation as resolved.
Show resolved Hide resolved
} catch (err) {
const { version: reactDomVersion } = require(`react-dom/package.json`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hot-loader/react-dom has versions starting from 16.7.0. Technically we support ^16.4.2 so the warning is not actionable for users on react versions between those 2 - worth silencing the warning if version is below 16.7? There are no hooks there anyway (assuming this is only needed for hooks support)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll do 16.8.0 because that's when hooks are a thing and you'll only need it for hooks.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know specific details but React 16.6+ features may not work. from the error/warning message implies it's not just hooks? (or maybe message is just not updated - not sure if I remember correctly but hooks were expected to land in 16.7 but didn't)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improved semver checks. These are all the patches that they have needed to do https://github.com/gaearon/react-hot-loader/blob/master/src/webpack/patch.js

const { major, minor } = semver.parse(reactDomVersion)
console.warn(
`React-Hot-Loader: please install "@hot-loader/react-dom@${major}.${minor}" to make sure all features of React are working.`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

patch part doesn't need to match?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not available for every patch version of react so that's the reason why I didn't do it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What will happen when there is version mismatch between react and @hot-loader/react-dom (given that patch is not available for everything, I guess we could limit question to different minor versions)?

I guess the behaviour itself is undefined - but would users see any warnings about this (that's going from the messaging here that major and minor should be the same for those 2 packages)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added an extra warning to the code, in my tests if your version is higher I haven't found any immediate issue but of course, there are probably some subtle changes.

)
}
}

const target =
stage === `build-html` || stage === `develop-html` ? `node` : `web`
if (target === `web`) {
Expand Down