docusaurus: šŸ› Prerendering fails when dependency includes `new URL('empty.js', import.meta.url);`

šŸš€ Feature:

Some mechanism to avoid loading modules which are incompatible with prerendering

Have you read the Contributing Guidelines on issues?

Yes

Motivation

I’m working on adding a ā€œplaygroundā€ page to the https://relay.dev docs, and that requires pulling in a Wasm module generated by wasm-pack. This module is incompatible with prerendering in multiple ways:

  • References globals which are only available on Web.
  • References import.meta.url.

I tried making this module import a lazy import (using import(moduleName)) and conditionally only importing it if ExecutionEnvironment.canUseDOM) is true, but it still seems to parse the module and error.

Pitch

It would be useful if there was some way to conditionally import the module in such a way that it would not be parsed/validated/run when doing prerendering. (Ideally this could be done without forcing the import to become a runtime import).

If that’s not feasible, another option would be a way to specify (via config?) that a given route should not be prerendered at all.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 17

Most upvoted comments

Will take a look tomorrow.

Can you tell me which error you had exactly?

Can you show me a successful integration of your playground in another React App that I could try to port to Docusaurus?

Webpack 5 definitively process new URL() as part of its new asset system

Le lun. 7 juin 2021 Ơ 22:10, Jordan Eldredge @.***> a Ʃcrit :

It looks like the solution proposed in #2494 https://github.com/facebook/docusaurus/issues/2494 will not work in my case. It looks like the presence of a require() or import() is enough to trigger the error, even if that import is never actually performed during prerendering.

I suspect some transpilation step is converting new URL(ā€˜empty.js’, import.meta.url); into something that references __filename and some subsequent validation is erroring on undefined variables, all before the code is even executed.

Here’s a minimal repro:

// some-page.js // Use a variable to avoid triggering dead code elimination.let temp = false; // This always-false condition demonstrates that the error triggered even when the code does not execute.// So <BrowserOnly /> and friends are insufficient to resolve the bug.if (temp) { require(ā€˜./dependency.js’);} export default function App() { return null;}

// dependnecy.js new URL(ā€˜empty.js’, import.meta.url);

// empty.js // This file intentionally left blank

This results in the following error:

ReferenceError: __filename is not defined error building locale=en Error: Failed to compile with errors. at @.***/core/lib/webpack/utils.js:198:24 at […redacted…]Relay/oss/github/website/node_modules/webpack/lib/MultiCompiler.js:554:14 at processQueueWorker ([…redacted…]Relay/oss/github/website/node_modules/webpack/lib/MultiCompiler.js:492:6) at processTicksAndRejections (internal/process/task_queues.js:76:11)

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/facebook/docusaurus/issues/4922#issuecomment-856221733, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAFW6PUPLS5XP6AMN4TO2NLTRURUTANCNFSM46IGW46A .

Sorry but I still can’t understand where the files should be created exactly.

A repro would really help, you can also open a PR modifying the docusaurus site itself.

At least please provide absolute paths, not just the filenames.

Le mer. 9 juin 2021 Ơ 22:38, Jordan Eldredge @.***> a Ʃcrit :

Thanks for taking a look. Sorry it’s difficult to pin down.

empty.js needs to exist, but its contents are not important. If you don’t supply an import path, Webpack won’t interpret it as a dynamic import and thus the problematic transformation won’t be applied. If you supply a path that is invalid you will get an error about not being able to locate the module, which obscures the error I’m reporting. So we need to point to a file that exits, but its contents are irrelevant (which is why I left it blank).

dependnecy.js is a third party module which I don’t have easy control over. In practice we do own the module, but it’s generated by wasm-pack https://rustwasm.github.io/wasm-pack/, so we don’t have much control over its syntax.

Here’s a very simple way to reproduce:

Take any working docusarus site (version 2.0.0-beta.0) and add the line new URL(ā€˜ā€¦/empty.js’, import.meta.url); to one of its pages (ensuring empty.js points to a file that exists).

This will cause the error ReferenceError: __filename is not defined when prerendering (yarn build), but will work fine in the client (yarn start).

The fact that this code causes an build error is problematic because:

  1. In our use case, that line exists in an NPM module that we can’t easily change.
  2. There’s no way to have prerendering skip trying to prerender the page which includes it.

If that syntax can be made to work in pre rendering mode that would be ideal. If not, some workaround which allows us to avoid loading/transforming that module during prerendering would also help us work around the issue.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/facebook/docusaurus/issues/4922#issuecomment-858084310, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAFW6PUXTD6GO66ZO22PIS3TR7GN7ANCNFSM46IGW46A .