cd0ebd8e8c
### 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
20 lines
445 B
TypeScript
20 lines
445 B
TypeScript
'use client'
|
|
|
|
import React from 'react'
|
|
import { NEXT_DYNAMIC_NO_SSR_CODE } from './no-ssr-error'
|
|
|
|
export function suspense() {
|
|
const error = new Error(NEXT_DYNAMIC_NO_SSR_CODE)
|
|
;(error as any).digest = NEXT_DYNAMIC_NO_SSR_CODE
|
|
throw error
|
|
}
|
|
|
|
type Child = React.ReactElement<any, any>
|
|
|
|
export default function NoSSR({ children }: { children: Child }): Child {
|
|
if (typeof window === 'undefined') {
|
|
suspense()
|
|
}
|
|
|
|
return children
|
|
}
|