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

Upgrade to DS beta.21 breaks SSR builds with useDocsVersion error #7686

Closed
4 of 7 tasks
markerikson opened this issue Jun 27, 2022 · 10 comments
Closed
4 of 7 tasks

Upgrade to DS beta.21 breaks SSR builds with useDocsVersion error #7686

markerikson opened this issue Jun 27, 2022 · 10 comments
Labels
closed: question This issue is a user error/misunderstanding.

Comments

@markerikson
Copy link

markerikson commented Jun 27, 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

I just tried upgrading Redux Toolkit's website from beta.7 to beta.21, and I'm seeing a variation on the "can't find chalk" error that was discussed in #7398:

TypeError: source_default(...).bold is not a function
TypeError: source_default(...).bold is not a function
TypeError: source_default(...).bold is not a function
[ERROR] Unable to build website for locale en.
[ERROR] Error: Failed to compile with errors.
    at D:\Projects\redux\redux-toolkit\node_modules\@docusaurus\core\lib\webpack\utils.js:180:24

fter going into serverEntry.js inside of node_modules, and commenting out every use of chalk in the error handling, and adding an additional console.error('Actual error: ', err) statement, I'm finally getting something meaningful:

[ERROR] Docusaurus server-side rendering could not render static page with path /rtk-query/usage/error-handling.
Actual error:  ReactContextError
    at useDocsVersion (main:9127:99)
    at DocVersionBanner (main:9136:814)
    at zb (main:81525:195)
    at Cb (main:81528:254)
    at W (main:81534:89)
    at Db (main:81537:98)
    at Eb (main:81536:122)
    at W (main:81534:345)
    at Db (main:81537:98)
    at Cb (main:81529:131) {
  message: 'Hook useDocsVersion is called outside the <DocsVersionProvider>. '
}

except that seems to be internal to Docusaurus and I have no idea why that provider doesn't exist.

so, three problems here:

  • The actual error isn't being printed at all
  • The chalk usages appear to be broken
  • I'm getting this useDocsVersion error just from upgrading DS

I'm seeing the same build failures both locally and in CI.

FWIW, I was just able to upgrade the Redux core docs from beta.18 to beta.21 with no errors, so maybe it has to do with RTK's Yarn monorepo?

Reproducible demo

reduxjs/redux-toolkit#2458

Steps to reproduce

  1. Clone the Redux Toolkit repo as of branch https://github.com/reduxjs/redux-toolkit/tree/docs/ds2-21-updates , as shown in Update Docusaurus to 2.b21 reduxjs/redux-toolkit#2458
  2. Run yarn at the root to install
  3. cd website
  4. yarn build

Expected behavior

The build would succeed cleanly, with no errors

Actual behavior

Per the description, and after adding additional logging to node_modules/@docusaurus/core/lib/client/serverEntry.js, the actual error appears to be

[ERROR] Docusaurus server-side rendering could not render static page with path /rtk-query/usage/error-handling.
Actual error:  ReactContextError
    at useDocsVersion (main:9127:99)
    at DocVersionBanner (main:9136:814)
    at zb (main:81525:195)
    at Cb (main:81528:254)
    at W (main:81534:89)
    at Db (main:81537:98)
    at Eb (main:81536:122)
    at W (main:81534:345)
    at Db (main:81537:98)
    at Cb (main:81529:131) {
  message: 'Hook useDocsVersion is called outside the <DocsVersionProvider>. '
}

So, somehow useDocsVersion isn't finding a provider after the upgrade.

Your environment

Self-service

  • I'd be willing to fix this bug myself.
@markerikson markerikson 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 labels Jun 27, 2022
@Josh-Cena Josh-Cena added status: needs more information There is not enough information to take action on the issue. and removed status: needs triage This issue has not been triaged by maintainers labels Jun 27, 2022
@slorber
Copy link
Collaborator

slorber commented Jun 29, 2022

@markerikson you have a custom DocPage component:

docLayoutComponent: '../src/theme/DocPageWithBraveWarning',

Our new entrypoint now provides multiple providers so that all subcomponents can access docs/version data easily with hooks anywhere (ie no props needed anymore):

<DocsVersionProvider version={versionMetadata}>
  <DocsSidebarProvider name={sidebarName} items={sidebarItems}>
    <DocPageLayout>{docElement}</DocPageLayout>
  </DocsSidebarProvider>
</DocsVersionProvider>

Instead of providing a custom config entry point for that page (that you now have to maintain yourself over time, ensuring it remains compatible with Docusaurus), you can try to swizzle components instead.


Looks like @msutkowski added a Brave warning to Docusaurus documents: reduxjs/redux-toolkit@599d4b8#diff-eaeffea00bcc3667ab8ddf261520fc47589a396fb6eb14afd916f40b98e4d682

Not 100% sure but it looks like we can summarize this customization as:

<div>
  <BraveWarning />
  <MDXProvider components={MDXComponents}>{children}</MDXProvider>
</div>

This is a lot of copied code for such small customization.

We have split the DocPage component into much smaller parts to make these kinds of customizations much easier: you would swizzle a much smaller component instead. That remains a burden on your side to maintain, but a much smaller one, less likely to break on upgrades.

For example, solutions you can try:

Swizzle eject @theme/DocItem/Content:

yarn swizzle @docusaurus/theme-classic DocItem/Content --eject --typescript --danger

export default function DocItemContent({children}: Props): JSX.Element {
  const syntheticTitle = useSyntheticTitle();
  return (
    <div className={clsx(ThemeClassNames.docs.docMarkdown, 'markdown')}>
      {syntheticTitle && (
        <header>
          <Heading as="h1">{syntheticTitle}</Heading>
        </header>
      )}
      <BraveWarning />
      <MDXContent>{children}</MDXContent>
    </div>
  );
}

Note: If the warning should also be displayed in MDX blog posts and MDX pages, you can also eject MDXContent, this component directly wraps any MDX content before rendering it.

Swizzle wrap @theme/DocItem/Content:

yarn swizzle @docusaurus/theme-classic DocItem/Content --wrap --typescript --danger

export default function ContentWrapper(props: Props): JSX.Element {
  return (
    <Content {...props}>
      <BraveWarning />
      {props.children}
    </Content>
  );
}

Both solutions works. We usually prefer to wrap as it is less likely to break on an upgrade.

Note these components are still marked as "unsafe" to swizzle (require the --danger CLI flag) because we are not ready to commit to SemVer retro compatibility on those.

In any case: it is still better than ejecting the DocPage component like you previously did: it is much larger/complex and we don't provide SemVer compatibility on it either 😅 Like we have seen here: it broke on an upgrade due to internal changes.

Does it make sense to you?

@slorber
Copy link
Collaborator

slorber commented Jun 29, 2022

Regarding the chalk errors, not sure what is happening 🤷‍♂️

Per the description, and after adding additional logging to node_modules/@docusaurus/core/lib/client/serverEntry.js, the actual error appears to be

What did you change here?

@Josh-Cena
Copy link
Collaborator

The chalk errors happen when SSR throws an error and tries to log a message. To this day I don’t know exactly how that happens. Usually re-installing fixes it.

@markerikson markerikson changed the title Upgrade to DS alpha.21 breaks SSR builds with useDocsVersion error Upgrade to DS beta.21 breaks SSR builds with useDocsVersion error Jun 29, 2022
@pranabdas
Copy link
Contributor

pranabdas commented Jul 1, 2022

In case it gives any additional hint: probably I see related issue with the latest canary version in one of my projects which uses @easyops-cn/docusaurus-search-local. When I try to build site:

[ERROR] Docusaurus server-side rendering could not render static page with path /404.html.
[ERROR] Docusaurus server-side rendering could not render static page with path /search.
[ERROR] Docusaurus server-side rendering could not render static page with path /.
[ERROR] Docusaurus server-side rendering could not render static page with path /xxxx.
// ... Snipped: multiple such lines

ReactContextError
ReactContextError
ReactContextError
// ... Snipped: multiple such lines
[ERROR] Unable to build website for locale en.
[ERROR] Error: Failed to compile with errors.
    at /workspaces/xxxxl/node_modules/@docusaurus/core/lib/webpack/utils.js:180:24
    at /workspaces/xxxx/node_modules/webpack/lib/MultiCompiler.js:554:14
    at processQueueWorker (/workspaces/xxxx/node_modules/webpack/lib/MultiCompiler.js:491:6)
    at processTicksAndRejections (node:internal/process/task_queues:78:11)

When I try to serve:
Screenshot 2022-07-01 at 7 53 19 PM

In the browser console:
Screenshot 2022-07-01 at 8 16 39 PM

Steps to reproduce:

  1. Create a brand new Docusaurus site:
npx create-docusaurus@latest my-website classic
  1. Install @easyops-cn/docusaurus-search-local:
cd my-website
npm install --save @easyops-cn/docusaurus-search-local
  1. Include following in docusaurus.config.js:
  themes: [
    [
      require.resolve("@easyops-cn/docusaurus-search-local"),
      {
        hashed: true,
      },
    ],
  ],
  1. Install latest canary:
npm i --save-exact @docusaurus/core@canary @docusaurus/preset-classic@canary
  1. Try to serve or build.
npm start
npm run build

@markerikson
Copy link
Author

FWIW we were able to fix RTK's docs build by following the advice here. This can probably be closed.

@Josh-Cena
Copy link
Collaborator

@pranabdas Your error is because you are using a different version of @docusaurus/theme-common from what the search plugin is using, which causes the context provider and consumer to read from different contexts. It's unrelated. If you are using an external plugin that does not declare peer dependency on theme-common (and tolerate canary versions), you'll very likely not be able to use canary.

@markerikson Great to know—let's close this then.

@Josh-Cena Josh-Cena closed this as not planned Won't fix, can't repro, duplicate, stale Jul 1, 2022
@Josh-Cena Josh-Cena added closed: question This issue is a user error/misunderstanding. and removed bug An error in the Docusaurus core causing instability or issues with its execution status: needs more information There is not enough information to take action on the issue. labels Jul 1, 2022
@slorber
Copy link
Collaborator

slorber commented Jul 6, 2022

@pranabdas I can reproduce your problem and it doesn't seem like there are 2 different versions of @docusaurus/theme-common

This is not related to the current issue, so let's discuss it in another place.

Looks like the search plugin introduced changes that makes it break on canary
Not sure why exactly that fails but will report on the PR there: easyops-cn/docusaurus-search-local#205

@slorber
Copy link
Collaborator

slorber commented Jul 6, 2022

@pranabdas see #7728

thomasheartman added a commit to Unleash/unleash that referenced this issue Nov 11, 2022
## Issue

So, we've got an issue with our docs build not working. When building
for production, we get an error that looks a little bit like this:

```
$ docusaurus build
[INFO] [en] Creating an optimized production build...

✔ Client


✖ Server
  Compiled with some errors in 40.85s



TypeError: source_default(...).bold is not a function
TypeError: source_default(...).bold is not a function
[ERROR] Unable to build website for locale en.
[ERROR] Error: Failed to compile with errors.
    at /Users/thomas/projects/work/unleash/website/node_modules/@docusaurus/core/lib/webpack/utils.js:180:24
    at /Users/thomas/projects/work/unleash/website/node_modules/webpack/lib/MultiCompiler.js:554:14
    at processQueueWorker (/Users/thomas/projects/work/unleash/website/node_modules/webpack/lib/MultiCompiler.js:491:6)
    at processTicksAndRejections (node:internal/process/task_queues:78:11)
[INFO] Docusaurus version: 2.2.0
Node version: v16.14.0
error Command failed with exit code 1.
```

Which isn't very helpful at all. If you go into
`/node_modules/@docusaurus/core/lib/client/serverEntry.js` and modify
the `render` function to log the actual error and remove anything
chalk-related, you get this instead:

```
$ docusaurus build
[INFO] [en] Creating an optimized production build...

✔ Client


✖ Server
  Compiled with some errors in 44.62s

Actual error: Error: Unexpected: cant find current sidebar in context
    at useCurrentSidebarCategory (main:11618:247)
    at MDXContent (main:38139:1593)
    at Fb (main:149154:44)
    at Ib (main:149156:254)
    at W (main:149162:89)
    at Jb (main:149165:98)
    at Ib (main:149157:145)
    at W (main:149162:89)
    at Jb (main:149165:98)
    at Ib (main:149157:145)
Actual error: Error: Unexpected: cant find current sidebar in context
    at useCurrentSidebarCategory (main:11618:247)
    at MDXContent (main:38513:1469)
    at Fb (main:149154:44)
    at Ib (main:149156:254)
    at W (main:149162:89)
    at Jb (main:149165:98)
    at Ib (main:149157:145)
    at W (main:149162:89)
    at Jb (main:149165:98)
    at Ib (main:149157:145)


Error: Unexpected: cant find current sidebar in context
Error: Unexpected: cant find current sidebar in context
[ERROR] Unable to build website for locale en.
[ERROR] Error: Failed to compile with errors.
    at /Users/thomas/projects/work/unleash/website/node_modules/@docusaurus/core/lib/webpack/utils.js:180:24
    at /Users/thomas/projects/work/unleash/website/node_modules/webpack/lib/MultiCompiler.js:554:14
    at processQueueWorker (/Users/thomas/projects/work/unleash/website/node_modules/webpack/lib/MultiCompiler.js:491:6)
    at processTicksAndRejections (node:internal/process/task_queues:78:11)
[INFO] Docusaurus version: 2.2.0
Node version: v16.14.0
error Command failed with exit code 1.
```

That's better, but it's still not very clear.

## Getting more info

We've had problems with a similar error message before. Last time it was
caused by an empty file that docusaurus couldn't process.

A similar issue has also been described in [ this docusaurus GitHub
issue ](facebook/docusaurus#7686). That's also
what gave me the idea of changing the logging in the dependency.

I'm currently unsure whether this is caused by the openapi docs or
something else. I've been in touch with the [openapi plugin
maintainer](PaloAltoNetworks/docusaurus-openapi-docs#323)
and he has been able to see the same error when building for prod
locally, but it was due to some old generated files.

Worth noting: this only seems to affect the prod build. Building for dev
(`yarn docusaurus start`) works just fine. It also fails locally **and**
in CI, so it _is_ an issue.

## Updating the logging
To get better logging, you can go into the
`/node_modules/@docusaurus/core/lib/client/serverEntry.js` file and
update the `render` function from

```js
export default async function render(locals) {
    try {
        return await doRender(locals);
    }
    catch (err) {
        // We are not using logger in this file, because it seems to fail with some
        // compilers / some polyfill methods. This is very likely a bug, but in the
        // long term, when we output native ES modules in SSR, the bug will be gone.
        // prettier-ignore
        console.error(chalk.red(`${chalk.bold('[ERROR]')} Docusaurus server-side rendering could not render static page with path ${chalk.cyan.underline(locals.path)}.`));
        const isNotDefinedErrorRegex = /(?:window|document|localStorage|navigator|alert|location|buffer|self) is not defined/i;
        if (isNotDefinedErrorRegex.test(err.message)) {
            // prettier-ignore
            console.info(`${chalk.cyan.bold('[INFO]')} It looks like you are using code that should run on the client-side only.
To get around it, try using ${chalk.cyan('`<BrowserOnly>`')} (${chalk.cyan.underline('https://docusaurus.io/docs/docusaurus-core/#browseronly')}) or ${chalk.cyan('`ExecutionEnvironment`')} (${chalk.cyan.underline('https://docusaurus.io/docs/docusaurus-core/#executionenvironment')}).
It might also require to wrap your client code in ${chalk.cyan('`useEffect`')} hook and/or import a third-party library dynamically (if any).`);
        }
        throw err;
    }
}
```

to

```js
export default async function render(locals) {
    try {
        return await doRender(locals);
    }
    catch (err) {
        console.error(err)
        throw err;
    }
}
```

That'll yield the errors about the current sidebar in context.


## Root cause

Found the issue! 🙋🏼 It's explained in [this comment on the openapi docs
integration](PaloAltoNetworks/docusaurus-openapi-docs#323 (comment))
for now, but in short: we have tags defined that we don't use. They're
being picked up by docusaurus, but don't have the proper context. That's
causing this.

The previously mentioned comment is included here for easy finding in
the future:

### Root cause explanation

The OpenAPI spec we use to generate the docs has a number of tags listed
at the root level. This is necessary for this plugin to pick up tag
categories and is, as far as I can tell, also how it _should_ be done.

However, not all of those tags are in use. Specifically, there's 2 tags
that are not.

When the plugin generates docs from the spec, it generates pages for all
endpoints and all tags and groups them by tag. However, it seems likely
that if a tag doesn't have any associated endpoints, then it won't get
added to the sidebar because there's no endpoint that references it.

But the doc files for these tags do end up lying around in the directory
regardless, and when docusaurus tries to pick up the files in the
generated directory, it also tries to pick up the unused tag files. But
because they're not part of a sidebar, they end up throwing errors
because they can't find the sidebar context.

### How I found it

The fact that I got more instances of the error message without the
sidebar ref than with it made me pay more attention to the number of
errors. I decided to check how many files were in the generated
directory and how many files were referenced from the generated sidebar.
Turns out the difference there was **2**: there were two generated files
in the directory that the sidebar didn't reference.

At this point, it was easy enough to try and delete those files before
rebuilding, and wouldn't you know: it worked!

### Our use case

Now, why do we have tags that are unused in the root spec? Can't we just
remove them?

That's a good question with a bit of a complicated answer. Unleash uses
an open core model and the OpenAPI integration is part of that open
core. The closed-source parts of Unleash are located in another repo and
extend the open-source distribution.

Because the OpenAPI spec is configured in the open-source part,
enterprise-only tags etc also need to be configured there. Then, when
the changes are absorbed into enterprise, we can use the tags there.

It gets more complicated because we use an enterprise instance to
generate the docs (because we want enterprise-endpoints to be listed
too). The instance uses the latest released instance of Unleash to have
the docs most accurately reflect the current state of things.

So, in this case, the tags have been added, but not yet used by any
endpoints, which suddenly causes this build failure. We can add the tags
to the enterprise-version, but the spec wouldn't be updated before the
next release regardless, which will probably be in a week or so.

This isn't an ideal setup, but .. it is what it is.

## Solutions and workarounds

As mentioned in the previous section, the reason the build was failing
was that there were unused tag files that docusaurus tried to include in
the build. Because they don't belong to a sidebar, the compilation
failed.

I've reported the issue to the openapi plugin maintainers and am waiting
for a response.

However, it seems that having unused root tags declared is invalid
according to the spec, so it's something we should look into fixing in
the future.

### Current workaround: cleaning script

The current workaround is to extend the api cleaning script to manually
remove the unused tag files.

### Ideal solution: filter root-level tags

Ideally, we shouldn't list unused OpenAPI tags on the root level at all.
However, because of the way we add root-level tags (as a predefined,
static lists, refer to `src/lib/openapi/index.ts`) and endpoints
(dynamically added at runtime) today, we don't really have a clear way
to filter the list of tags. This gets even more complicated when taking
the enterprise functionality and the potential extra tags they must
have.

This is, however, something that should definitely be looked into.
Working with OpenAPI across multipile repos is already troublesome, so
this is just yet another thing to look into.
@ianobermiller
Copy link

For anyone who ended up here with TypeError: source_default(...).bold is not a function and wants to see what the actual underlying error is:

  • open node_modules/@docusaurus/core/lib/client/serverEntry.js
  • Find the line with Docusaurus server-side rendering could not render static page with path
  • Remove all references to chalk

E.g. before:

console.error(chalk.red(`${chalk.bold('[ERROR]')} Docusaurus server-side rendering could not render static page with path ${chalk.cyan.underline(locals.path)}.`));

after:

console.error((`${('[ERROR]')} Docusaurus server-side rendering could not render static page with path ${(locals.path)}.`));

In my case it was Error: Minified React error #31; and pointed me to the failing path.

@Addono
Copy link

Addono commented Apr 28, 2023

Continuing on the answer from @ianobermiller: Removing all references to chalk can be done by doing a regex-replace in node_modules/@docusaurus/core/lib/client/serverEntry.js in VS Code.

Just let it search for the following RegEx and replace it all with the empty string and you're good to go:

chalk\.[\w\.]+

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed: question This issue is a user error/misunderstanding.
Projects
None yet
Development

No branches or pull requests

6 participants