vercel / next.js

The React Framework
https://nextjs.org
MIT License
124.86k stars 26.66k forks source link

Error in dev mode with turbopack using Chakra-UI components from server components #69159

Open dkokotov opened 3 weeks ago

dkokotov commented 3 weeks ago

Link to the code that reproduces this issue

https://github.com/CNaught-Inc/nextjs-turbo-chakra-issue-repro

To Reproduce

  1. Run the application with --turbo
  2. Go to http://localhost:3000 - get an error
  3. Note that it works if you run it without --turbo.

Current vs. Expected behavior

The error when running with --turbo is

TypeError: createContext only works in Client Components. Add the "use client" directive at the top of the file to use it. Read more: https://nextjs.org/docs/messages/context-in-server-component`

Note that the Box component being used from Chakra UI already has "use client" in it, and per chakra docs it should be possible to use it directly from the server component - and it does work when not using Turbopack.

Also note that if I wrap the use of Box in a local component with "use client" at the top, then all works ok (as illustrated in https://github.com/CNaught-Inc/nextjs-turbo-chakra-issue-repro/blob/main/app/working/page.tsx). So the issue seems to be that Turbopack does not "see" the "use client" from the chakra package.

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.6.0: Mon Jul 29 21:14:46 PDT 2024; root:xnu-10063.141.2~1/RELEASE_ARM64_T6031
  Available memory (MB): 65536
  Available CPU cores: 16
Binaries:
  Node: 22.5.1
  npm: 10.8.2
  Yarn: 1.22.19
  pnpm: 8.7.5
Relevant Packages:
  next: 14.2.5 // Latest available version is detected (14.2.5).
  eslint-config-next: N/A
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.4.5
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Turbopack

Which stage(s) are affected? (Select all that apply)

next dev (local)

Additional context

Node that the above repo is using Next.js 14.2.5, but I also verified the same behavior occurs with the latest 15 canary.

I had previously reported this as a comment on a related issue: https://github.com/vercel/next.js/issues/64412#issuecomment-2052436233. That issue was fixed but the behavior reported in this issue remains.

While the workaround works, it requires creating a lot of extra files. It's particularly annoying if trying to use the "fragment colocation / masking" pattern for GraphQL (described in https://gql-tada.0no.co/guides/fragment-colocation or https://the-guild.dev/blog/unleash-the-power-of-fragments-with-graphql-codegen). This is because we need to import GraphQL fragments into our server component to use them in a query. If those fragments are colocated with the components that render them (which would use Chakra components), this presents an issue - because of the issue described here, those components must be in files marked as "use client" - but after that, you can no longer import the GraphQL fragments from those files into the query executed in the server component (as described in this issue: https://github.com/apollographql/apollo-client-nextjs/issues/27). The only solution seems to be to split the GraphQL fragments into separate files which can be imported both by the parent query and by the client component, which adds a lot of overhead.

dkokotov commented 3 weeks ago

I should not that I don't think the issue is Chakra-specific. I suspect the same would happen when using any component marked with "use client" from a different package with next dev --turbo.

samcx commented 3 weeks ago

@dkokotov Thank you for submitting an issue!

I can confirm the difference between :turbopack-spin: dev and Webpack dev. Will be sharing with the team?