Docusaurus: Non declared dependencies throwing errors in Yarn v2 (berry)

Created on 10 Apr 2020  路  13Comments  路  Source: facebook/docusaurus

馃悰 Bug Report

Attempting to use Docusaurus v2 with Yarn v2 (berry).
As soon as i run yarn build the build explodes with dependency errors from yarn v2.

Lots of peer dependencies aren't specified and yarn v2 doesn't know what to do.

Example error

Error: @docusaurus/core tried to access @docusaurus/plugin-content-blog, but it isn't declared in its dependencies; this makes the require call ambiguous and unsound.

Interesting that this doesn't happen in yarn v1, but it seems to be due to no dependencies/peer dependencies being specified for the various docusaurus packages.

Steps to reproduce

  • Install/have yarn v2 as the package manager for project
  • Install docusaurus v2
  • run yarn build.

I've tried to install every dependency yarn says it can't find, but it's an endless process, and i still haven't managed to get a build to work.

Basically, right now, docusaurus v2 is not compatible with yarn v2 馃槩

bug advanced

All 13 comments

This is a little tricky. Docusaurus v2 runs on a plugin system, so @docusaurus/core should not even know about the existence of @docusaurus/plugin-content-blog and should not declare plugin-specific stuff as its peer dependencies.
Right now Docusaurus relies on @docusaurus/theme-classic's dependencies (including @docusaurus/plugin-content-blog) to be hoisted to the root of node_modules. This assumption is usually true, so right now things just happen to work. To be really strict, users might need to declare dependencies on things like @docusaurus/plugin-content-blog explicitly to make it work with Yarn v2.

Me too, I try out everything but it's still hopeless. Even I try to change pnpMode to loose. :(

I'm running into a sim issue with @vue/cli due to its plugin system. Yarn docs invite us to ping @arcanis so they can track these issues..

I made an example to show how you can use some hacks to make docusaurus v2 work with pnp: https://github.com/SamChou19815/docusaurus-yarn-v2-example
I'm trying to add some fixes upstream.

The latest release would fix most of the problems. However, you still need pnpMode: loose. See https://github.com/SamChou19815/docusaurus-yarn-v2-example for latest instructions.

It's possible to use yarn without enabling loose mode if you add the Webpack PNP plugin and patch a few of the missing dependencies. The PNP plugin won't be required with webpack5

https://github.com/jgeschwendt/repro-docusaurus-yarn2/commits/patch

@jgeschwendt PNP plugin is already added: https://github.com/facebook/docusaurus/pull/2796
We still need pnp loose because theme-classic has a bunch of dependencies that doesn't properly dependencies, and it will inject import '@mdx-js/react' on user's behalf for docs page.

Awesome, didn't know that, I pushed up a new commit removing the plugin. Is there something wrong with resolving those missing dependencies in the .yarnrc.yml file? It seems like the alpha.56 release fixed a lot of the package extensions I had to help along.

packageExtensions:
  "@docusaurus/preset-classic@*":
    dependencies:
      "@docusaurus/utils": ^2.0.0-alpha.56
  "@docusaurus/mdx-loader@*":
    dependencies:
      react: "*"
  "@docusaurus/theme-classic@*":
    dependencies:
      core-js: "*"

yarnPath: .yarn/releases/yarn-2.0.0-rc.33.js

I just tried to use Docusaurus for one of my projects so I investigated a bit. I think there are two things at play. The first is the following error:

Error: @docusaurus/core tried to access @docusaurus/preset-classic, but it isn't declared in its dependencies; this makes the require call ambiguous and unsound.

Required package: @docusaurus/preset-classic (via "@docusaurus/preset-classic")
Required by: @docusaurus/core

This is because @docusaurus/core calls importFresh (here) in order to load the plugin. This third-party in turns calls resolveFrom based on a flawed heuristic, but essentially it's the equivalent of require.resolve with no paths option. As a result, the resolution is done against the dependencies declared by @docusaurus/core, not the top-level package, and the error is correct (Docusaurus is at risk of problems caused by incorrect hoisting, regardless of the package manager).

To fix that, simply process presetModuleImport as such:

const resolvedModuleImport = createRequire(path.join(context.siteDir, 'package.json')).resolve(presetModuleImport);
const presetModule: any = importFresh(resolvedModuleImport);

This will ensure that the preset is resolved against the dependencies declared by the site directory, which is likely what you intend to do. Note that this doesn't use any non-standard API - createRequire is standard since Node 12, and polyfills exist before that.

A second problem (but really, not that much of a problem if it works for you) is that @docusaurus/core is defined as a regular dependency of the plugins (rather than a peer dependency). In general this can be source of troubles since you can't ensure that you'll get the exact same version in every plugin. Perhaps that's something you may want to look into, but that's more of an advice than anything 馃檪

Thanks @arcanis, not very familiar with these problems but trying to figure this out 馃槄

A second problem (but really, not that much of a problem if it works for you) is that @docusaurus/core is defined as a regular dependency of the plugins (rather than a peer dependency). In general this can be source of troubles since you can't ensure that you'll get the exact same version in every plugin. Perhaps that's something you may want to look into, but that's more of an advice than anything 馃檪

Due to issues in the past, we actually have a runtime check to ensure all versions are the same, as using different versions often lead to unexpected failures.

You should get an error like:

image

We are going to release very soon, let me know tomorrow afternoon if you still have issues with latest version, or if we can close this issue

@arcanis fix released in 2.0.0-alpha.69

closing, assuming it's fixed, but let me know if it's not

Was this page helpful?
0 / 5 - 0 ratings