rsnext/packages/next/server/load-components.ts
Shu Ding df6df1959e
Parallelize requirePage when loading components (#29494)
We can potentially speed it up a little bit by using `Promise.all` here. This was raised by @devknoll in https://github.com/vercel/next.js/pull/29470#pullrequestreview-766039044.
2021-09-29 14:42:35 +00:00

124 lines
3.1 KiB
TypeScript

import {
BUILD_MANIFEST,
REACT_LOADABLE_MANIFEST,
} from '../shared/lib/constants'
import { join } from 'path'
import { requirePage } from './require'
import { BuildManifest } from './get-page-files'
import { AppType, DocumentType } from '../shared/lib/utils'
import {
PageConfig,
GetStaticPaths,
GetServerSideProps,
GetStaticProps,
} from 'next/types'
export function interopDefault(mod: any) {
return mod.default || mod
}
export type ManifestItem = {
id: number | string
files: string[]
}
type ReactLoadableManifest = { [moduleId: string]: ManifestItem }
export type LoadComponentsReturnType = {
Component: React.ComponentType
pageConfig: PageConfig
buildManifest: BuildManifest
reactLoadableManifest: ReactLoadableManifest
Document: DocumentType
App: AppType
getStaticProps?: GetStaticProps
getStaticPaths?: GetStaticPaths
getServerSideProps?: GetServerSideProps
ComponentMod: any
}
export async function loadDefaultErrorComponents(distDir: string) {
const Document = interopDefault(require('next/dist/pages/_document'))
const App = interopDefault(require('next/dist/pages/_app'))
const ComponentMod = require('next/dist/pages/_error')
const Component = interopDefault(ComponentMod)
return {
App,
Document,
Component,
pageConfig: {},
buildManifest: require(join(distDir, `fallback-${BUILD_MANIFEST}`)),
reactLoadableManifest: {},
ComponentMod,
}
}
export async function loadComponents(
distDir: string,
pathname: string,
serverless: boolean
): Promise<LoadComponentsReturnType> {
if (serverless) {
const ComponentMod = await requirePage(pathname, distDir, serverless)
if (typeof ComponentMod === 'string') {
return {
Component: ComponentMod as any,
pageConfig: {},
ComponentMod,
} as LoadComponentsReturnType
}
let {
default: Component,
getStaticProps,
getStaticPaths,
getServerSideProps,
} = ComponentMod
Component = await Component
getStaticProps = await getStaticProps
getStaticPaths = await getStaticPaths
getServerSideProps = await getServerSideProps
const pageConfig = (await ComponentMod.config) || {}
return {
Component,
pageConfig,
getStaticProps,
getStaticPaths,
getServerSideProps,
ComponentMod,
} as LoadComponentsReturnType
}
const [DocumentMod, AppMod, ComponentMod] = await Promise.all([
requirePage('/_document', distDir, serverless),
requirePage('/_app', distDir, serverless),
requirePage(pathname, distDir, serverless),
])
const [buildManifest, reactLoadableManifest] = await Promise.all([
require(join(distDir, BUILD_MANIFEST)),
require(join(distDir, REACT_LOADABLE_MANIFEST)),
])
const Component = interopDefault(ComponentMod)
const Document = interopDefault(DocumentMod)
const App = interopDefault(AppMod)
const { getServerSideProps, getStaticProps, getStaticPaths } = ComponentMod
return {
App,
Document,
Component,
buildManifest,
reactLoadableManifest,
pageConfig: ComponentMod.config || {},
ComponentMod,
getServerSideProps,
getStaticProps,
getStaticPaths,
}
}