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

Conflicting versions when using canary releases + third-party plugins #7728

Open
4 of 7 tasks
slorber opened this issue Jul 6, 2022 · 4 comments
Open
4 of 7 tasks
Labels
bug An error in the Docusaurus core causing instability or issues with its execution external This issue is caused by an external dependency and not Docusaurus.

Comments

@slorber
Copy link
Collaborator

slorber commented Jul 6, 2022

Have you read the Contributing Guidelines on issues?

Prerequisites

  • I'm using the latest version of Docusaurus.
  • I have tried the npm run clear or yarn clear command.
  • I have tried rm -rf node_modules yarn.lock package-lock.json and re-installing packages.
  • I have tried creating a repro with https://new.docusaurus.io.
  • I have read the console error message carefully (if applicable).

Description

Let's imagine you are using a canary release of Docusaurus, and also a third-party plugin.

You likely have this in your package.json file:

    "@docusaurus/core": "0.0.0-5170",
    "@docusaurus/preset-classic": "0.0.0-5170",
    "@easyops-cn/docusaurus-search-local": "^0.28.0",

Problem: @easyops-cn/docusaurus-search-local depends on many Docusaurus core packages with semver range ^2.0.0-beta.20, and ^2.0.0 does not match 0.0.0

This potentially leads to duplicate core package installs in your repo, and multiple versions of the same package being used at runtime.

This is particularly problematic for packages exporting React providers because contexts are now duplicated, leading to weird issues like this one #7686 (comment)

A workaround is to use things like npm/yarn resolutions so that the user forces the package manager to duplicate packages.

We'll probably move @docusaurus/theme-common to peerDependency in the future, as it's the package most likely to cause troubles (exporting many React contexts)

Another possibility is to change another time the canary versioning scheme, maybe using 3.0.0-something for the canaries after we release 2.0? This should be changed carefully, as this scheme has been the source of troubles in the past, see #5295)

Reproducible demo

No response

Steps to reproduce

see #7686 (comment)

Expected behavior

Use canary + third-party plugin without duplicated packages and weird React context issues

Actual behavior

see #7686 (comment): unexpected React context issues

Your environment

  • Public source code:
  • Public site URL:
  • Docusaurus version used:
  • Environment name and version (e.g. Chrome 89, Node.js 16.4):
  • Operating system and version (e.g. Ubuntu 20.04.2 LTS):

Self-service

  • I'd be willing to fix this bug myself.
@slorber slorber added bug An error in the Docusaurus core causing instability or issues with its execution status: needs triage This issue has not been triaged by maintainers and removed status: needs triage This issue has not been triaged by maintainers labels Jul 6, 2022
@Josh-Cena Josh-Cena added the external This issue is caused by an external dependency and not Docusaurus. label Jul 6, 2022
@octogonz
Copy link

@slorber I'd like to add that the error messages can be highly confusing in this situation.

The F12 console error looks like this:

docsPreferredVersion.js:formatted:179 Uncaught ReactContextError
    at useDocsPreferredVersionContext (docsPreferredVersion.js:formatted:179:15)
    at useDocsPreferredVersionByPluginId (docsPreferredVersion.js:formatted:216:34)
    at useContextualSearchFilters (searchUtils.js:21:543)
    at useTypesenseContextualFilters (useTypesenseContextualFacetFilters.js:12:152)
    at DocSearch (index.js:33:1501)
    at renderWithHooks (react-dom.development.js:14985:18)
    at mountIndeterminateComponent (react-dom.development.js:17811:13)
    at beginWork (react-dom.development.js:19049:16)
    at HTMLUnknownElement.callCallback (react-dom.development.js:3945:14)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:3994:16)

...and if you dig out the error string, it's complaining that useDocsPreferredVersionContext() was called outside of its <DocsPreferredVersionContextProvider> scope. I spent nearly 2 hours trying to debug that false premise. 😆

At first I was bisecting the Git history, looking for some Docusaurus release where <DocsPreferredVersionContextProvider> or some other part of the render tree might have been moved around. Then eventually I realized that there is in fact a <DocsPreferredVersionContextProvider> -- and useDocsPreferredVersionContext() does find it, but... not always?! This led into the react__WEBPACK_IMPORTED_MODULE_0__.useContext)(Context); and the sprawling logic fishing things out of contexts.

It was just a very unlucky direction to happen to choose for debugging: The reason why useDocsPreferredVersionContext() was failing is that it's defined in a secondary module, a different version of @docusaurus/theme-common that Webpack has found in node_modules and bundled for the third-party plugin. The <DocsPreferredVersionContextProvider> scope does exist, but its symbol doesn't match the useDocsPreferredVersionContext() instance that's trying to call it.

And so the fix is to override versions and eliminate the side-by-side versions from node_modules.

But wow, is there SOME WAY that Docusaurus's plugin framework could provide better safeguards or diagnostics for this trap? My scenario was pretty common -- just trying to upgrade Docusaurus, getting a weird crash, and believing what the error message was telling me. 🙂

@slorber
Copy link
Collaborator Author

slorber commented Aug 24, 2022

Sorry about your experience

This kind of error can happen in any client-side app using npm unfortunately, and it's a quite common issue in React and Node.js world.

  • The good thing is that at least you get an error.
  • The worst thing could be that you inadvertently include multiple versions of React in your bundle, loading a lot of useless additional JS without even being aware of the problem.

But wow, is there SOME WAY that Docusaurus's plugin framework could provide better safeguards or diagnostics for this trap?

I don't have a clear answer to that. Maybe we could scan the node modules for duplicated packages or something 🤷‍♂️ Curious to know what others are doing to prevent this kind of issue.

I wish React would fail fast in such a case, but afaik since React 17 they support better micro-frontends and using multiple versions of React on the same page is perfectly allowed

@yannickrocks
Copy link

yannickrocks commented Feb 28, 2023

Im not sure if this is related but is there a fixed for what you suggested @octogonz
I get the following
image

Using React 17.0.1 and Docusaurus 2.3.1

@octogonz
Copy link

Im not sure if this is related but is there a fixed for what you suggested

@yannickrocks Yes, as I explained the problem is that two different instances of React got installed in the node_modules folder. Since we're using PNPM, we were able to use Lockfile Explorer to figure out the cause of this problem and fix it. Usually it just involves making the package.json versions consistent between projects, or sometimes adding an override such as .pnpmfile.cjs or Yarn "resolutions".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug An error in the Docusaurus core causing instability or issues with its execution external This issue is caused by an external dependency and not Docusaurus.
Projects
None yet
Development

No branches or pull requests

4 participants