import React from 'react' import Loadable from './loadable' const isServerSide = typeof window === 'undefined' export type LoaderComponent
= Promise< React.ComponentType
| { default: React.ComponentType
} > export type Loader
= (() => LoaderComponent
) | LoaderComponent
export type LoaderMap = { [mdule: string]: () => Loader = LoadableGeneratedOptions & {
loading?: ({
error,
isLoading,
pastDelay,
}: {
error?: Error | null
isLoading?: boolean
pastDelay?: boolean
retry?: () => void
timedOut?: boolean
}) => JSX.Element | null
loader?: Loader | LoaderMap
loadableGenerated?: LoadableGeneratedOptions
ssr?: boolean
}
export type LoadableOptions = LoadableBaseOptions
export type DynamicOptions = LoadableBaseOptions
export type LoadableFn = (
opts: LoadableOptions
) => React.ComponentType
export type LoadableComponent = React.ComponentType
export function noSSR (
LoadableInitializer: LoadableFn ,
loadableOptions: LoadableOptions
): React.ComponentType {
// Removing webpack and modules means react-loadable won't try preloading
delete loadableOptions.webpack
delete loadableOptions.modules
// This check is necessary to prevent react-loadable from initializing on the server
if (!isServerSide) {
return LoadableInitializer(loadableOptions)
}
const Loading = loadableOptions.loading!
// This will only be rendered on the server side
return () => (
(options: O):
export default function dynamic (
dynamicOptions: DynamicOptions | Loader ,
options?: DynamicOptions
): React.ComponentType {
let loadableFn: LoadableFn = Loadable
let loadableOptions: LoadableOptions = {
// A loading component is not required, so we default it
loading: ({ error, isLoading, pastDelay }) => {
if (!pastDelay) return null
if (process.env.NODE_ENV === 'development') {
if (isLoading) {
return null
}
if (error) {
return (
{error.message}
Loading something
{error.stack}