Skip to content

Commit

Permalink
refactor: move changes into new ppr test suite
Browse files Browse the repository at this point in the history
  • Loading branch information
wyattjoh committed Dec 14, 2023
1 parent 03ecbd4 commit f4105c1
Show file tree
Hide file tree
Showing 11 changed files with 349 additions and 185 deletions.
65 changes: 39 additions & 26 deletions packages/next/src/server/base-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1756,7 +1756,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
let hasStaticPaths = !!components.getStaticPaths
const isServerAction = getIsServerAction(req)
const hasGetInitialProps = !!components.Component?.getInitialProps
let isSSG = !!components.getStaticProps
let isStaticSiteGeneration = !!components.getStaticProps

// Compute the iSSG cache key. We use the rewroteUrl since
// pages with fallback: false are allowed to be rewritten to
Expand Down Expand Up @@ -1813,9 +1813,9 @@ export default abstract class Server<ServerOptions extends Options = Options> {
// TODO: make this more generic
req.headers['x-now-route-matches']
) {
isSSG = true
isStaticSiteGeneration = true
} else if (!this.renderOpts.dev) {
isSSG ||=
isStaticSiteGeneration ||=
!!prerenderManifest.routes[pathname === '/index' ? '/' : pathname]
}

Expand All @@ -1826,7 +1826,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
(req.headers['x-nextjs-data'] &&
(this.serverOptions as any).webServerConfig)
) &&
(isSSG || hasServerProps)
(isStaticSiteGeneration || hasServerProps)

/**
* If true, this indicates that the request being made is for an app
Expand All @@ -1841,7 +1841,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
// resolve to a static data route we bail early to avoid
// unexpected SSR invocations
if (
!isSSG &&
!isStaticSiteGeneration &&
req.headers['x-middleware-prefetch'] &&
!(is404Page || pathname === '/_error')
) {
Expand All @@ -1859,7 +1859,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
// normalize req.url for SSG paths as it is not exposed
// to getStaticProps and the asPath should not expose /_next/data
if (
isSSG &&
isStaticSiteGeneration &&
this.minimalMode &&
req.headers['x-matched-path'] &&
req.url.startsWith('/_next/data')
Expand Down Expand Up @@ -1921,7 +1921,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
pathname !== '/_error' &&
req.method !== 'HEAD' &&
req.method !== 'GET' &&
(typeof components.Component === 'string' || isSSG)
(typeof components.Component === 'string' || isStaticSiteGeneration)
) {
res.statusCode = 405
res.setHeader('Allow', ['GET', 'HEAD'])
Expand Down Expand Up @@ -1955,7 +1955,10 @@ export default abstract class Server<ServerOptions extends Options = Options> {
// be static so we can collect revalidate and populate the
// cache if there are no dynamic data requirements
opts.supportsDynamicHTML =
!isSSG && !isBotRequest && !query.amp && isSupportedDocument
!isStaticSiteGeneration &&
!isBotRequest &&
!query.amp &&
isSupportedDocument
opts.isBot = isBotRequest
}

Expand All @@ -1969,7 +1972,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
opts.supportsDynamicHTML = true
}

const defaultLocale = isSSG
const defaultLocale = isStaticSiteGeneration
? this.nextConfig.i18n?.defaultLocale
: query.__nextDefaultLocale

Expand All @@ -1979,7 +1982,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
let previewData: PreviewData
let isPreviewMode = false

if (hasServerProps || isSSG) {
if (hasServerProps || isStaticSiteGeneration) {
// For the edge runtime, we don't support preview mode in SSG.
if (process.env.NEXT_RUNTIME !== 'edge') {
const { tryGetPreviewData } =
Expand All @@ -1992,7 +1995,12 @@ export default abstract class Server<ServerOptions extends Options = Options> {
if (isAppPath) {
res.setHeader('vary', RSC_VARY_HEADER)

if (!this.renderOpts.dev && !isPreviewMode && isSSG && isRSCRequest) {
if (
!this.renderOpts.dev &&
!isPreviewMode &&
isStaticSiteGeneration &&
isRSCRequest
) {
// If this is an RSC request but we aren't in minimal mode, then we mark
// that this is a data request so that we can generate the flight data
// only.
Expand All @@ -2017,12 +2025,16 @@ export default abstract class Server<ServerOptions extends Options = Options> {
let isOnDemandRevalidate = false
let revalidateOnlyGenerated = false

if (isSSG) {
if (isStaticSiteGeneration) {
;({ isOnDemandRevalidate, revalidateOnlyGenerated } =
checkIsOnDemandRevalidate(req, this.renderOpts.previewProps))
}

if (isSSG && this.minimalMode && req.headers['x-matched-path']) {
if (
isStaticSiteGeneration &&
this.minimalMode &&
req.headers['x-matched-path']
) {
// the url value is already correct when the matched-path header is set
resolvedUrlPathname = urlPathname
}
Expand Down Expand Up @@ -2070,7 +2082,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
let ssgCacheKey: string | null = null
if (
!isPreviewMode &&
isSSG &&
isStaticSiteGeneration &&
!opts.supportsDynamicHTML &&
!isServerAction &&
!minimalPostponed &&
Expand All @@ -2083,7 +2095,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
}${query.amp ? '.amp' : ''}`
}

if ((is404Page || is500Page) && isSSG) {
if ((is404Page || is500Page) && isStaticSiteGeneration) {
ssgCacheKey = `${locale ? `/${locale}` : ''}${pathname}${
query.amp ? '.amp' : ''
}`
Expand Down Expand Up @@ -2152,7 +2164,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
(!isDataReq && opts.dev === true) ||
// If this is not SSG or does not have static paths, then it supports
// dynamic HTML.
(!isSSG && !hasStaticPaths) ||
(!isStaticSiteGeneration && !hasStaticPaths) ||
// If this request has provided postponed data, it supports dynamic
// HTML.
typeof postponed === 'string' ||
Expand Down Expand Up @@ -2188,7 +2200,8 @@ export default abstract class Server<ServerOptions extends Options = Options> {
// page and it is not being resumed from a postponed render and
// it is not a dynamic RSC request then it is a revalidation
// request.
isRevalidate: isSSG && !postponed && !isDynamicRSCRequest,
isRevalidate:
isStaticSiteGeneration && !postponed && !isDynamicRSCRequest,
originalPathname: components.ComponentMod.originalPathname,
serverActions: this.nextConfig.experimental.serverActions,
}
Expand Down Expand Up @@ -2233,7 +2246,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
originalPathname: components.ComponentMod.originalPathname,
supportsDynamicHTML,
incrementalCache,
isRevalidate: isSSG,
isRevalidate: isStaticSiteGeneration,
},
}

Expand All @@ -2253,7 +2266,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {

// If the request is for a static response, we can cache it so long
// as it's not edge.
if (isSSG && process.env.NEXT_RUNTIME !== 'edge') {
if (isStaticSiteGeneration && process.env.NEXT_RUNTIME !== 'edge') {
const blob = await response.blob()

// Copy the headers from the response.
Expand Down Expand Up @@ -2288,7 +2301,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
return null
} catch (err) {
// If this is during static generation, throw the error again.
if (isSSG) throw err
if (isStaticSiteGeneration) throw err

Log.error(err)

Expand Down Expand Up @@ -2362,7 +2375,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
// to know whether the path is actually static or not
if (
isAppPath &&
isSSG &&
isStaticSiteGeneration &&
metadata.revalidate === 0 &&
!this.renderOpts.dev &&
!renderOpts.experimental.ppr
Expand Down Expand Up @@ -2605,7 +2618,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
cacheEntry.value?.kind === 'PAGE' && !!cacheEntry.value.postponed

if (
isSSG &&
isStaticSiteGeneration &&
!this.minimalMode &&
// We don't want to send a cache header for requests that contain dynamic
// data. If this is a Dynamic RSC request or wasn't a Prefetch RSC
Expand Down Expand Up @@ -2665,7 +2678,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {

// If this isn't SSG, then we should set change the header only if it is
// not set already.
else if (!isSSG) {
else if (!isStaticSiteGeneration) {
if (!res.getHeader('Cache-Control')) {
revalidate = 0
}
Expand Down Expand Up @@ -2740,7 +2753,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
} else if (cachedData.kind === 'ROUTE') {
const headers = { ...cachedData.headers }

if (!(this.minimalMode && isSSG)) {
if (!(this.minimalMode && isStaticSiteGeneration)) {
delete headers[NEXT_CACHE_TAGS_HEADER]
}

Expand All @@ -2765,7 +2778,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
if (cachedData.headers) {
const headers = { ...cachedData.headers }

if (!this.minimalMode || !isSSG) {
if (!this.minimalMode || !isStaticSiteGeneration) {
delete headers[NEXT_CACHE_TAGS_HEADER]
}

Expand All @@ -2787,7 +2800,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {

if (
this.minimalMode &&
isSSG &&
isStaticSiteGeneration &&
cachedData.headers?.[NEXT_CACHE_TAGS_HEADER]
) {
res.setHeader(
Expand Down
12 changes: 2 additions & 10 deletions test/e2e/app-dir/ppr-full/app/layout.jsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
import { Links } from '../components/links'
import { Layout } from '../components/layout'

export default ({ children }) => {
return (
<html>
<body>
<h1>Partial Prerendering</h1>
<p>
Below are links that are associated with different pages that all will
partially prerender
</p>
<aside>
<Links />
</aside>
<main>{children}</main>
<Layout>{children}</Layout>
</body>
</html>
)
Expand Down
7 changes: 6 additions & 1 deletion test/e2e/app-dir/ppr-full/app/static/page.jsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
export default () => {
return 'Static'
return (
<dl>
<dt>Pathname</dt>
<dd data-pathname="/static">/static</dd>
</dl>
)
}
49 changes: 25 additions & 24 deletions test/e2e/app-dir/ppr-full/components/dynamic.jsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,38 @@
import React from 'react'
import { headers } from 'next/headers'
import React, { use } from 'react'
import * as next from 'next/headers'

export const Dynamic = ({ pathname, fallback }) => {
if (fallback) {
return <div>Dynamic Loading...</div>
}

const headers = next.headers()
const messages = []
const names = ['x-test-input', 'user-agent']
const list = headers()
for (const name of ['x-test-input', 'user-agent']) {
messages.push({ name, value: headers.get(name) })
}

for (const name of names) {
messages.push({ name, value: list.get(name) })
const delay = headers.get('x-delay')
if (delay) {
use(new Promise((resolve) => setTimeout(resolve, parseInt(delay, 10))))
}

return (
<div id="needle">
<dl>
{pathname && (
<>
<dt>Pathname</dt>
<dd>{pathname}</dd>
</>
)}
{messages.map(({ name, value }) => (
<React.Fragment key={name}>
<dt>
Header: <code>{name}</code>
</dt>
<dd>{value ?? `MISSING:${name.toUpperCase()}`}</dd>
</React.Fragment>
))}
</dl>
</div>
<dl>
{pathname && (
<>
<dt>Pathname</dt>
<dd data-pathname={pathname}>{pathname}</dd>
</>
)}
{messages.map(({ name, value }) => (
<React.Fragment key={name}>
<dt>
Header: <code>{name}</code>
</dt>
<dd>{value ?? `MISSING:${name.toUpperCase()}`}</dd>
</React.Fragment>
))}
</dl>
)
}
18 changes: 18 additions & 0 deletions test/e2e/app-dir/ppr-full/components/layout.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react'
import { Links } from './links'

export const Layout = ({ children }) => {
return (
<>
<h1>Partial Prerendering</h1>
<p>
Below are links that are associated with different pages that all will
partially prerender
</p>
<aside>
<Links />
</aside>
<main>{children}</main>
</>
)
}
13 changes: 13 additions & 0 deletions test/e2e/app-dir/ppr-full/components/links.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@ const links = [
{ href: '/no-suspense/nested/b', tag: 'no suspense, on-demand' },
{ href: '/no-suspense/nested/c', tag: 'no suspense, on-demand' },
{ href: '/dynamic/force-dynamic', tag: "dynamic = 'force-dynamic'" },
{
href: '/dynamic/force-dynamic/nested/a',
tag: "dynamic = 'force-dynamic', on-demand, no-gsp",
},
{
href: '/dynamic/force-dynamic/nested/b',
tag: "dynamic = 'force-dynamic', on-demand, no-gsp",
},
{
href: '/dynamic/force-dynamic/nested/c',
tag: "dynamic = 'force-dynamic', on-demand, no-gsp",
},
{ href: '/dynamic/force-static', tag: "dynamic = 'force-static'" },
{ href: '/edge/suspense', tag: 'edge, pre-generated' },
{ href: '/edge/suspense/a', tag: 'edge, pre-generated' },
Expand All @@ -27,6 +39,7 @@ const links = [
{ href: '/edge/no-suspense/a', tag: 'edge, no suspense, pre-generated' },
{ href: '/edge/no-suspense/b', tag: 'edge, no suspense, on-demand' },
{ href: '/edge/no-suspense/c', tag: 'edge, no suspense, on-demand' },
{ href: '/pages', tag: 'pages' },
]

export const Links = () => {
Expand Down
13 changes: 13 additions & 0 deletions test/e2e/app-dir/ppr-full/pages/pages.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react'
import { Layout } from '../components/layout'

export default () => {
return (
<Layout>
<dl>
<dt>Pathname</dt>
<dd data-pathname="/pages">/pages</dd>
</dl>
</Layout>
)
}

0 comments on commit f4105c1

Please sign in to comment.