-
Notifications
You must be signed in to change notification settings - Fork 26.1k
/
render.ts
129 lines (118 loc) · 3.53 KB
/
render.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import type { NextConfig } from '../../../../server/config-shared'
import type { DocumentType, AppType } from '../../../../shared/lib/utils'
import type { BuildManifest } from '../../../../server/get-page-files'
import type { ReactLoadableManifest } from '../../../../server/load-components'
import { NextRequest } from '../../../../server/web/spec-extension/request'
import WebServer from '../../../../server/web-server'
import {
WebNextRequest,
WebNextResponse,
} from '../../../../server/base-http/web'
// Polyfilled for `path-browserify` inside the Web Server.
process.cwd = () => ''
export function getRender({
dev,
page,
appMod,
pageMod,
errorMod,
error500Mod,
Document,
buildManifest,
reactLoadableManifest,
serverComponentManifest,
config,
buildId,
}: {
dev: boolean
page: string
appMod: any
pageMod: any
errorMod: any
error500Mod: any
Document: DocumentType
buildManifest: BuildManifest
reactLoadableManifest: ReactLoadableManifest
serverComponentManifest: any | null
config: NextConfig
buildId: string
}) {
const baseLoadComponentResult = {
dev,
buildManifest,
reactLoadableManifest,
Document,
App: appMod.default as AppType,
AppMod: appMod,
}
const server = new WebServer({
conf: config,
minimalMode: true,
webServerConfig: {
extendRenderOpts: {
buildId,
reactRoot: true,
runtime: 'edge',
supportsDynamicHTML: true,
disableOptimizedLoading: true,
serverComponentManifest,
},
loadComponent: async (pathname) => {
if (pathname === page) {
return {
...baseLoadComponentResult,
Component: pageMod.default,
pageConfig: pageMod.config || {},
getStaticProps: pageMod.getStaticProps,
getServerSideProps: pageMod.getServerSideProps,
getStaticPaths: pageMod.getStaticPaths,
ComponentMod: pageMod,
}
}
// If there is a custom 500 page, we need to handle it separately.
if (pathname === '/500' && error500Mod) {
return {
...baseLoadComponentResult,
Component: error500Mod.default,
pageConfig: error500Mod.config || {},
getStaticProps: error500Mod.getStaticProps,
getServerSideProps: error500Mod.getServerSideProps,
getStaticPaths: error500Mod.getStaticPaths,
ComponentMod: error500Mod,
}
}
if (pathname === '/_error') {
return {
...baseLoadComponentResult,
Component: errorMod.default,
pageConfig: errorMod.config || {},
getStaticProps: errorMod.getStaticProps,
getServerSideProps: errorMod.getServerSideProps,
getStaticPaths: errorMod.getStaticPaths,
ComponentMod: errorMod,
}
}
return null
},
},
})
const requestHandler = server.getRequestHandler()
return async function render(request: NextRequest) {
const { nextUrl: url } = request
const { searchParams } = url
const query = Object.fromEntries(searchParams)
// Preflight request
if (request.method === 'HEAD') {
// Hint the client that the matched route is a SSR page.
return new Response(null, {
headers: {
'x-middleware-ssr': '1',
},
})
}
const extendedReq = new WebNextRequest(request)
const extendedRes = new WebNextResponse()
requestHandler(extendedReq, extendedRes)
return await extendedRes.toResponse()
}
}