preact icon indicating copy to clipboard operation
preact copied to clipboard

`esmExternals: false` required when using Preact + Next.js

Open brianjenkins94 opened this issue 1 year ago • 3 comments

  • [x] Check if updating to the latest Preact version resolves the issue

Related

  • https://github.com/shuding/nextra/issues/589
  • https://github.com/preactjs/preact/issues/2690
  • https://github.com/preactjs/preact/issues/3512
  • https://github.com/preactjs/preact/issues/3393
  • https://github.com/preactjs/next-plugin-preact/issues/53
  • https://github.com/preactjs/preact/issues/3512

Describe the bug

I get the error below when trying to use Preact with Next.js. Another user (@DylanMashini) is doing something similar and seeing the same error. Their CodeSandbox is more concise than mine.

It seems like it has something to do with preact/hooks and/or preact-render-to-string but it might also have something to do with duplicated Preact bundles.

This issue has a workaround, by setting esmExternals: false but ideally I'd like not to have to set this.

Stacktrace:

error - TypeError: Cannot read properties of undefined (reading '__H')
    at p (/node_modules/preact/hooks/dist/hooks.mjs:1:158)
    at F (/node_modules/preact/hooks/dist/hooks.mjs:1:875)
    at s (/node_modules/preact/hooks/dist/hooks.mjs:1:636)
    at y (/node_modules/@headlessui/react/dist/hooks/use-sync-refs.js:1:178)
    at /node_modules/@headlessui/react/dist/components/listbox/listbox.js:1:4473
    at Object.t (/node_modules/preact/compat/dist/compat.mjs:1:1363)
    at m (\node_modules\preact-render-to-string\dist\commonjs.js:1:2609)
    at m (\node_modules\preact-render-to-string\dist\commonjs.js:1:2724)
    at m (\node_modules\preact-render-to-string\dist\commonjs.js:1:2724)
    at m (\node_modules\preact-render-to-string\dist\commonjs.js:1:2724) {
  page: '/'
}

To Reproduce

CodeSandbox: https://codesandbox.io/s/nextra-preact-dxkxev

Steps to reproduce the behavior:

  1. Open a new terminal (bottom right)
  2. npm start
  3. A popup should come up (bottom right) that says "Port 3000 Opened", click "Open browser pane"
  4. See error

Workaround:

Add the following to next.config.mjs:

{
  "experimental": {
    "esmExternals": false
  }
}

Expected behavior

Page should render, no errors.

brianjenkins94 avatar Jul 26 '22 12:07 brianjenkins94

Heh, I don't think there is much we can do here as it looks like we are following all ESM rules and we are successfully being used natively in the browser as well as by projects like vite who also are esm-only 😅 I assume this creates duplicate entries somehow, would be valuable to inspect the bundle and see how the transpilation creates these dupes

JoviDeCroock avatar Jul 26 '22 15:07 JoviDeCroock

What @JoviDeCroock says is spot on. This looks like nextjs is not following the spec and does something wrong in their ESM resolution.

marvinhagemeister avatar Jul 26 '22 15:07 marvinhagemeister

One of these times I'll file the issue on the right tracker, I'm sure of it! 😅

brianjenkins94 avatar Jul 26 '22 15:07 brianjenkins94