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
[appDir] Dynamically importing a Client Component using the 'use client' directive from a Server Component causes "Error: object is not a function" #43147
Comments
Also the link of deployed build in Vercel proving that it works in production and also that is still prerendering even though |
After reading a bit more about this section of the React Server Components RFC I could check that this is possibly by design and that I still think we could improve the error messaging here, will open a PR for this ASAP. |
Correct, you won't need Although the error message is a bit unclear and we could improve it. See also: https://beta.nextjs.org/docs/routing/loading-ui#manually-defining-suspense-boundaries |
Hi @brvnonascimento , when you import a client component in server component, it will become a module reference which is the "object" that marked in the error. But as @balazsorban44 mentioned above, you don't actually need to do in that way you can just move the part you don't want to have in client bundle to server components then leave the rest to client components, and directly importing them will be fine. Will improve the error for it |
After discussion, this case should be able to support, the effect is client will be split into different chunk but still be loadable throught this way. I'm addressing the support for this in #42589 |
### Summary Migrate `next/dynamic` to implementation based on `React.lazy` and `Suspense`. Then it becomes easier to migrate the existing code in pages to layouts. Then we can support both `ssr` and `loading` option for `next/dynamic`. For `loading` option, it will work like `Suspense`'s `fallback` property ```js <Suspense fallback={loading}> <DynamicComponent /> </Suspense> ``` For `ssr` option, by default `React.lazy` supports SSR, but we'll disable the `ssr: false` case for dynamic import in server components since there's no client side involved. Then we don't need `suspense` option anymore as react >= 18 is always required. Mark it as deprecated. It also supports to load client component dynamically in server components now. #### Code code changes * switch loadable component to `lazy` + `Suspense` * will make sure it's retuning a module from `loader()` to `loader().then(mod => ({ default: mod.default || mod }))` since `lazy()` only accepts loader returning a module * Inside suspense boundary, throwing an error for ssr: false, catch the error on server and client side and ignore it. * Ignore options like ssr: false for server components since they're on server, doesn't make sense * Remove legacy dynamic related transform #### Feature changes * `next/dynamic` will work in the same way across the board (appDir and pages) * For the throwing error, will make it become a API that throws error later in the future, so users can customize more with `Suspense` * You can load client components now in server components with dynamic. Resolves #43147 #### Tests * existing dynamic tests all work * add case: import client component and load through next/dynamic in server components ### Issues
This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you. |
Verify canary release
Provide environment information
What browser are you using? (if relevant)
Firefox 107.0
How are you deploying your application? (if relevant)
Vercel
Describe the Bug
Dynamically importing with
next/dynamic
a Client Component that uses ause/client
directive will cause anError: object is not a function
error in development. The production build runs fine though.Also noticed that adding
ssr: false
won't prevent the component from getting prerendered when runningnext build
. Addingsuspense: true
orsuspense: false
won't make a difference either.Expected Behavior
We should be able to dynamically import a component that makes heavy use of JavaScript in the client from a Server Component and use a custom Suspense-based fallback.
Link to reproduction - Issues with a link to complete (but minimal) reproduction code will be addressed faster
https://github.com/brvnonascimento/use-client-dynamic-bug
To Reproduce
yarn create next-app --experimental-app
'use client'
directivenext/dynamic
to import the given componentError: object is not a function
in developmentScreen.Recording.2022-11-20.at.04.16.21.mov
The text was updated successfully, but these errors were encountered: