Open BleddP opened 8 months ago
Thanks for writing this up. I have the same issue. My first load JS on some routes is huge because of it.
I can confirm the next/dynamic doesn't work. The solution we did for now was using React.lazy where we could. But yeah quite the regression compared to Pages Router ^^'
Link to the code that reproduces this issue
https://github.com/BleddP/app-dir-code-splitting-bug
To Reproduce
yarn
yarn dev
(or you can just go straight ahead andyarn build && yarn start
I have created four variations of the same page, they all use the spread operator as we want dynamic params to render a page from let's say a CMS.
The components in
[...bundled]
are imported asimport { ServerWrapper, ClientWrapper } from '@bundled-components'
as thebundled-components
directory has anindex.ts
file that exports everything from the components library. This helps with a DRY approach, and makes the code generally more readable and maintainable.There is no index.ts file in the
components
folder to export everything, so the components in[...components]
are imported as:Then, both pages (
...bundled
and...components
) import their components through a wrapper. One variant is wrapped in a server component, which attempts 1 regular import and 1 dynamic import. The other is wrapped in a client component, which attempts 1 regular import and 1 dynamic import.The problem here is that the dynamic import only works when components are not exported from
index.ts
and when they are wrapped in a client wrapper. This is entirely unclear from the current Next.js docs.Current vs. Expected behavior
According to the next.js docs: https://nextjs.org/docs/pages/building-your-application/optimizing/lazy-loading
This implies that inside a server component, I can use
dynamic
to lazy load a client component. But as evidenced by my reproduction repo, there is absolutely no code splitting / lazy loading happening when dynamically importing a client component in a server component.Expected vs current behaviour Expected: Any component that is imported using the
dynamic
import, is lazy loaded. Current: No component (not even client components) are lazy loaded if usingdynamic
from within a server componentAdditionally, the CSS is bundled together into the main page css, if the component is also dynamically imported from within a server component. It only splits the CSS, if the component is exclusively dynamically imported from another client component. This is very confusing, especially because the lazy loading really does not work as described in your docs.
Provide environment information
Which area(s) are affected? (Select all that apply)
App Router, Dynamic imports (next/dynamic)
Which stage(s) are affected? (Select all that apply)
next dev (local), next start (local)
Additional context
No response