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

Migrate to React 18 #7264

Closed
1 of 2 tasks
Josh-Cena opened this issue Apr 29, 2022 · 13 comments · Fixed by #8961
Closed
1 of 2 tasks

Migrate to React 18 #7264

Josh-Cena opened this issue Apr 29, 2022 · 13 comments · Fixed by #8961
Labels
domain: dependencies Proposal to upgrade a dependency across major versions proposal This issue is a proposal, usually non-trivial change
Milestone

Comments

@Josh-Cena
Copy link
Collaborator

Josh-Cena commented Apr 29, 2022

Have you read the Contributing Guidelines on issues?

For site maintainers

Upgrading to React 18 is optional—it won't break anything, but it won't do anything either. Until Docusaurus uses the new createRoot API, the site's behavior will still be the same as that in React 17. However, you may be able to use a few React 18 niceties like useId() (which I'm personally excited about for accessibility reasons).

If your dependency management bot wants to upgrade to React 18 for you, and it doesn't cause any problems (around peer dependencies), feel free to accept it.

Motivation

Unlike React 17, React 18 contains actual API changes that may not be backward-compatible (i.e. you can't take a React 18 program and expect it to run in a project installed with React 17). Therefore, migration to React 18 can only happen along two paths:

  1. We migrate to React 18 by using the new createRoot API, and throw an early error for anyone still installed with react@17, telling them to update their package.json.
    • Problem: breaks virtually every site, some sites already having a version of React in their monorepo may end up having duplicate copies, which opens a can of worms.
  2. We detect the version of React installed, and selectively uses ReactDOM.render or createRoot based on the version.
    • Problem: hacky code, slightly increases bundle size, and harder to maintain in the long run (refactoring hazards)

It is not good to move forward with either solution.

We have some preliminary work done in #7102, but it's far from being complete, and gets stalled in multiple places. The resolution is that as the 2.0 release is approaching, we'll likely stay on React 17 because the truth is, even many libraries are not fully prepared for React 18 yet! React 18 will be considered a breaking change and will come in v3.

The most urgent blocking issue is that MDX v1 doesn't declare React v18 in its peer dependencies range. Because the v1 line is effectively frozen, I believe there's no plan to fix this. Certain package managers (namely, npm v7 and pnpm) are strict about peer dependencies and will refuse to install properly if @mdx-js/react is installed alongside react@18. This will be confusing for the users, so it's another strong point why we'll delay it to v3: we'll only migrate to MDX v2 in Docusaurus v3 (#4029).

Since I don't think React 18 actually removed any API, there's not much we need to do on the code side. It's only about dependencies. Still, it would be nice if we can remove react-loadable (#3841), because it uses the deprecated componentWillMount lifecycle and prevents us from opting into StrictMode. Also, React 18 will bring support for new SSG APIs (including server-rendering Suspense), and we'll want to take the opportunity of prolonged migration time window to look into that as well.

Self-service

  • I'd be willing to do some initial work on this proposal myself.
@Josh-Cena Josh-Cena added proposal This issue is a proposal, usually non-trivial change pr: dependencies Pull requests that update a dependency file labels Apr 29, 2022
@Josh-Cena Josh-Cena added this to the 3.0.0 milestone Apr 29, 2022
@Josh-Cena Josh-Cena added domain: dependencies Proposal to upgrade a dependency across major versions and removed pr: dependencies Pull requests that update a dependency file labels May 4, 2022
FaberVitale added a commit to FaberVitale/redux-toolkit that referenced this issue Jun 12, 2022
@sanjaiyan-dev
Copy link
Contributor

sanjaiyan-dev commented Jul 31, 2022

Hi,

I thought we can incrementally adopt to React 18 which give easy migration process too 😊

  if (React.version.includes("18.")) {
    if (process.env.NODE_ENV === "production") {
      const { hydrateRoot } = require("react-dom/client");

      preload(window.location.pathname).then(() => {
        hydrateRoot(
          document.getElementById("__docusaurus"),
          <HelmetProvider>
            <BrowserRouter>
              <App />
            </BrowserRouter>
          </HelmetProvider>
        );
      });
    } else {
      const { createRoot } = require("react-dom/client");

      preload(window.location.pathname).then(() => {
        const docReactRoot = createRoot(
          document.getElementById("__docusaurus")
        );

        docReactRoot.render(
          <HelmetProvider>
            <BrowserRouter>
              <App />
            </BrowserRouter>
          </HelmetProvider>
        );
      });
    }
  } else {
    const ReactDOM = require("react-dom");
    const renderMethod =
      process.env.NODE_ENV === "production"
        ? ReactDOM.hydrate
        : ReactDOM.render;
    preload(window.location.pathname).then(() => {
      renderMethod(
        <HelmetProvider>
          <BrowserRouter>
            <App />
          </BrowserRouter>
        </HelmetProvider>,
        document.getElementById("__docusaurus")
      );
    });
  }

In above code we dynamically require the new react 18 dom lib with fallback for older versions :)

I am sorry if I made any errors/mistakes :(

@Josh-Cena
Copy link
Collaborator Author

@sanjaiyan-dev That falls under the realm of

Problem: hacky code, slightly increases bundle size, and harder to maintain in the long run (refactoring hazards)

I'm not really willing to maintain that code, but it's a nice path nevertheless. Let's wait till v3 is actually on the roadmap to decide what is best for us.

@sanjaiyan-dev
Copy link
Contributor

@sanjaiyan-dev That falls under the realm of

Problem: hacky code, slightly increases bundle size, and harder to maintain in the long run (refactoring hazards)

I'm not really willing to maintain that code, but it's a nice path nevertheless. Let's wait till v3 is actually on the roadmap to decide what is best for us.

Yh 💪🙌

@Eliav2
Copy link

Eliav2 commented Aug 29, 2022

So react 18 would never be supported on V2? only on the future version, Docusaurus V3?

There are some really nice features in React18.
For example, ReactDOMServer (which is used on production build) 18 allows lazy loading of React components, which in turn allows write and use of custom components that show a live preview of a component and its code.
Such custom components can't be written in ReactDOMServer 17 (but strangely supported on react 17. so would encounter errors on Docusaurus only on production build)

@Josh-Cena
Copy link
Collaborator Author

Josh-Cena commented Aug 30, 2022

We hope to release Docusaurus v3 very quickly. According to our release doc, it should be within a few months, so you should not worry about it too much. React 18 will be a major change, so no, it will not be backported. Also, we have abstracted all the build pipeline, and we hope you could develop without caring about the underlying plumbing infra.

@juliusmarminge
Copy link

When can we expect the first canary release that uses React 18? Saw that you have 3.0.0-alpha.0 but it's still on React 17?

SoYoung210 added a commit to h6s-dev/h6s that referenced this issue Nov 29, 2022
* fix(@h6s/website): revert bump react18

- facebook/docusaurus#7264
- docusaurus does not support react18 yet

* fix(@h6s-examples/react): resolve react18 warning

- update chakra-ui

* chore(@h6s-examples/react): chakra-ui breaking change migration
@perfectbase
Copy link

Hi! I have a problem that I think is related to this issue.
I have a monorepo (turborepo) and I can't have multiple versions of react in it. (otherwise react breaks)
I'm trying to change the docusaurus project's react dependency to 18, but npm install fails with:

peer react@"^16.13.1 || ^17.0.0" from @mdx-js/react@1.6.22

I noticed that next-auth has a similar project structure and is successfully using react 18 in the docusaurus project.

I tried to replicate it on my project, but wasn't successful. Does someone understand how they did it?
Is there anyway I can work around this problem?

Thank you in advance.

@juliusmarminge
Copy link

Hi! I have a problem that I think is related to this issue. I have a monorepo (turborepo) and I can't have multiple versions of react in it. (otherwise react breaks) I'm trying to change the docusaurus project's react dependency to 18, but npm install fails with:

peer react@"^16.13.1 || ^17.0.0" from @mdx-js/react@1.6.22

I noticed that next-auth has a similar project structure and is successfully using react 18 in the docusaurus project.

I tried to replicate it on my project, but wasn't successful. Does someone understand how they did it? Is there anyway I can work around this problem?

Thank you in advance.

Just disable strict peer dependencies. If you're on pnpm, create a .npmrc and put strict-peer-dependencies=false in it

@perfectbase
Copy link

@juliusmarminge thanks for the guidance!
I was able to make it work with the command npm i --legacy-peer-deps now that the lock file has the structure, I'm able to instal with only npm i.

@julrich
Copy link

julrich commented Jan 17, 2023

Would also love to know if there's an updated timeline somewhere for support. Wasn't able to come up with branches / tags to look at. Would be happy to play the guinea pig here! (we're actually "dependent" on React 18, because we'd love to integrate https://github.com/pacocoursey/cmdk with our docs)

@Sonic12040
Copy link

Is a contribution needed here to keep this item moving forward? I'd be happy to commit to this, as the peer deps poses problems for monorepos in particular.

@lachieh
Copy link
Contributor

lachieh commented Feb 24, 2023

@Sonic12040 React 18 and MDX2 are aimed at being supported with V3: #8469

@Sonic12040
Copy link

Thanks for that. I'll see what's open to contribute to 3.0!

raguiar9080 added a commit to lune-climate/lune-docs that referenced this issue May 25, 2023
We had some missing peer dependencies so add them. Current yarn install
output:
```
yarn install v1.22.19
warning ../../../package.json: No license field
[1/5] 🔍  Validating package.json...
[2/5] 🔍  Resolving packages...
[3/5] 🚚  Fetching packages...
[4/5] 🔗  Linking dependencies...
warning " > lune-ui-lib@1.3.4" has incorrect peer dependency "react@18.0.0".
warning " > lune-ui-lib@1.3.4" has unmet peer dependency "react-scripts@5.0.0".
warning "lune-ui-lib > worker-loader@3.0.8" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
[5/5] 🔨  Building fresh packages...
✨  Done in 9.45s.
```

The warnings that remain are a bit trickier to solve but they all come
from the ui-lib. The dependency on react is a current open issue with
docusaurus (facebook/docusaurus#7264), they
state that the move to react 18 will be done only on docusaurus v3.
Trying to upgrade manually I was faced with even more issues, so I
believe it's better to wait.
The other two dependencies I'm not sure should be needed so I think it's
something to solve on the ui-lib itself. I'll investigate the issue
deeper and possible solutions on another PR.

Signed-off-by: Ruben Aguiar <r.aguiar9080@gmail.com>
@slorber slorber modified the milestones: 3.x+, 3.0 Aug 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain: dependencies Proposal to upgrade a dependency across major versions proposal This issue is a proposal, usually non-trivial change
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants