99d4d6c5a4
(#31506 for context) This PR implements the minimum viable web server on top of the Next.js base server, and integrates it into our middleware (edge) SSR runtime to handle all the requests. This also addresses problems like missing dynamic routes support in our current handler. Note that this is the initial implementation with the assumption that the web server is running under minimal mode. Also later we can refactor the `__server_context` environment to properly passing the context via the constructor or methods.
89 lines
2.5 KiB
TypeScript
89 lines
2.5 KiB
TypeScript
import { stringifyRequest } from '../../stringify-request'
|
|
|
|
export default async function middlewareSSRLoader(this: any) {
|
|
const {
|
|
dev,
|
|
page,
|
|
buildId,
|
|
absolutePagePath,
|
|
absoluteAppPath,
|
|
absoluteDocumentPath,
|
|
absolute500Path,
|
|
absoluteErrorPath,
|
|
isServerComponent,
|
|
stringifiedConfig,
|
|
} = this.getOptions()
|
|
|
|
const stringifiedAbsolutePagePath = stringifyRequest(this, absolutePagePath)
|
|
const stringifiedAbsoluteAppPath = stringifyRequest(this, absoluteAppPath)
|
|
const stringifiedAbsolute500PagePath = stringifyRequest(
|
|
this,
|
|
absolute500Path || absoluteErrorPath
|
|
)
|
|
const stringifiedAbsoluteDocumentPath = stringifyRequest(
|
|
this,
|
|
absoluteDocumentPath
|
|
)
|
|
|
|
const transformed = `
|
|
import { adapter } from 'next/dist/server/web/adapter'
|
|
import { RouterContext } from 'next/dist/shared/lib/router-context'
|
|
|
|
import App from ${stringifiedAbsoluteAppPath}
|
|
import Document from ${stringifiedAbsoluteDocumentPath}
|
|
|
|
import { getRender } from 'next/dist/build/webpack/loaders/next-middleware-ssr-loader/render'
|
|
|
|
const pageMod = require(${stringifiedAbsolutePagePath})
|
|
const errorMod = require(${stringifiedAbsolute500PagePath})
|
|
|
|
const buildManifest = self.__BUILD_MANIFEST
|
|
const reactLoadableManifest = self.__REACT_LOADABLE_MANIFEST
|
|
const rscManifest = self.__RSC_MANIFEST
|
|
|
|
if (typeof pageMod.default !== 'function') {
|
|
throw new Error('Your page must export a \`default\` component')
|
|
}
|
|
|
|
// Set server context
|
|
self.__current_route = ${JSON.stringify(page)}
|
|
self.__server_context = {
|
|
Component: pageMod.default,
|
|
pageConfig: pageMod.config || {},
|
|
buildManifest,
|
|
reactLoadableManifest,
|
|
Document,
|
|
App,
|
|
getStaticProps: pageMod.getStaticProps,
|
|
getServerSideProps: pageMod.getServerSideProps,
|
|
getStaticPaths: pageMod.getStaticPaths,
|
|
ComponentMod: undefined,
|
|
serverComponentManifest: ${isServerComponent} ? rscManifest : null,
|
|
|
|
// components
|
|
errorMod,
|
|
|
|
// renderOpts
|
|
buildId: ${JSON.stringify(buildId)},
|
|
dev: ${dev},
|
|
env: process.env,
|
|
supportsDynamicHTML: true,
|
|
concurrentFeatures: true,
|
|
disableOptimizedLoading: true,
|
|
}
|
|
|
|
const render = getRender({
|
|
Document,
|
|
isServerComponent: ${isServerComponent},
|
|
config: ${stringifiedConfig},
|
|
})
|
|
|
|
export default function rscMiddleware(opts) {
|
|
return adapter({
|
|
...opts,
|
|
handler: render
|
|
})
|
|
}`
|
|
|
|
return transformed
|
|
}
|