react-error-boundary icon indicating copy to clipboard operation
react-error-boundary copied to clipboard

"use client" not appearing in the ESM entry

Open kentcdodds opened this issue 1 year ago • 5 comments

  • react-error-boundary version: 4.0.13 (latest)
  • node version: v20
  • npm version: v10

Relevant code or config

import { ErrorBoundary } from 'react-error-boundary'

What you did:

Using the node loader from react-server-dom-esm (https://github.com/facebook/react/blob/e373190faf3b994707f09488c1a7832f4a91e15a/packages/react-server-dom-esm/src/ReactFlightESMNodeLoader.js#L471-L481)

What happened:

react-error-boundary is not treated as a client component because the "use client" pragma doesn't appear in the ESM module (only the CJS module).

Problem description:

The problem is that node loaders can only transform native ESM modules. So the "use client" pragma needs to appear in the ESM module. Something in the build process doesn't make that work though.

Suggested solution:

My workaround is to create a separate module in my own codebase that adds the "use client" pragma and import that instead. I would love to not have to do that.

kentcdodds avatar Mar 25 '24 16:03 kentcdodds

PR welcome!

bvaughn avatar Mar 25 '24 16:03 bvaughn

I'm guessing the solution will be in the build tool: https://github.com/preconstruct/preconstruct

kentcdodds avatar Mar 25 '24 20:03 kentcdodds

I didn't see any issues referencing that in the preconstruct repo. I see a few mentions of "use client" in the CHANGELOG for versions 2.4-2.6, but this project is using v2.8 so it seems like those are unrelated. Maybe @Andarist knows of something?

bvaughn avatar Mar 25 '24 23:03 bvaughn

I opened a PR that might fix this here. It doesn't solve all the potential setups. I think that likely having the whole module marked with the 'use client' directive is common enough that maybe it's good enough of a change.

The problem is that node loaders can only transform native ESM modules.

Is this true? I'm not an expert on the subject but the code in this particular node loader indicates that it's just its decision to ignore everything that is not a module. So it doesn't look like an inherent limitation.

I recognize the issue here but to quote their README 😅 :

Experimental React Flight bindings for DOM using ESM. Use it at your own risk.

In a way, the issue seems to be not in a way how this package is structured but in their decision to ignore CJS files. I don't recall any mentions of 'use client' being an ESM-only feature.

Andarist avatar Mar 26 '24 07:03 Andarist

Thanks a ton for taking a look, @Andarist. I’m also not sure of the right thing to do here, really. So much about server components feels half baked right now.

bvaughn avatar Mar 26 '24 11:03 bvaughn