rsnext/packages/next/build/utils.ts

527 lines
14 KiB
TypeScript
Raw Normal View History

import chalk from 'chalk'
2019-12-14 07:39:59 +01:00
import gzipSize from 'gzip-size'
import textTable from 'next/dist/compiled/text-table'
import path from 'path'
import { isValidElementType } from 'react-is'
import stripAnsi from 'strip-ansi'
2019-12-12 17:20:24 +01:00
import { Redirect, Rewrite } from '../lib/check-custom-routes'
import { SPR_GET_INITIAL_PROPS_CONFLICT } from '../lib/constants'
import prettyBytes from '../lib/pretty-bytes'
import { recursiveReadDir } from '../lib/recursive-readdir'
2019-12-12 17:20:24 +01:00
import { DEFAULT_REDIRECT_STATUS } from '../next-server/lib/constants'
Add experimental SPR support (#8832) * initial commit for SPRv2 * Add initial SPR cache handling * update SPR handling * Implement SPR handling in render * Update tests, handle caching with serverless next start, add TODOs, and update manifest generating * Handle no prerender-manifest from not being used * Fix url.parse error * Apply suggestions from code review Co-Authored-By: Joe Haddad <joe.haddad@zeit.co> * Replace set with constants in next-page-config * simplify sprStatus.used * Add error if getStaticProps is used with getInitialProps * Remove stale TODO * Update revalidate values in SPR cache for non-seeded routes * Apply suggestions from code review * Remove concurrency type * Rename variable for clarity * Add copying prerender files during export * Add comment for clarity * Fix exporting * Update comment * Add additional note * Rename variable * Update to not re-export SPR pages from build * Hard navigate when fetching data fails * Remove default extension * Add brackets * Add checking output files to prerender tests * Adjust export move logic * Clarify behavior of export aggregation * Update variable names for clarity * Update tests * Add comment * s/an oxymoron/contradictory/ * rename * Extract error case * Add tests for exporting SPR pages and update /_next/data endpoint to end with .json * Relocate variable * Adjust route building * Rename to unstable * Rename unstable_getStaticParams * Fix linting * Only add this when a data request * Update prerender data tests * s/isServerless/isLikeServerless/ * Don't rely on query for `next start` in serverless mode * Rename var * Update renderedDuringBuild check * Add test for dynamic param with bracket * Fix serverless next start handling * remove todo * Adjust comment * Update calculateRevalidate * Remove cache logic from render.tsx * Remove extra imports * Move SPR cache logic to next-server * Remove old isDynamic prop * Add calling App getInitialProps for SPR pages * Update revalidate logic * Add isStale to SprCacheValue * Update headers for SPR * add awaiting pendingRevalidation * Dont return null for revalidation render * Adjust logic * Be sure to remove coalesced render * Fix data for serverless * Create a method coalescing utility * Remove TODO * Extract send payload helper * Wrap in-line * Move around some code * Add tests for de-duping and revalidating * Update prerender manifest test
2019-09-24 10:50:04 +02:00
import { getRouteMatcher, getRouteRegex } from '../next-server/lib/router/utils'
import { isDynamicRoute } from '../next-server/lib/router/utils/is-dynamic'
2019-12-12 17:20:24 +01:00
import { findPageFile } from '../server/lib/find-page-file'
2019-12-14 07:39:59 +01:00
const fileGzipStats: { [k: string]: Promise<number> } = {}
const fsStatGzip = (file: string) => {
if (fileGzipStats[file]) return fileGzipStats[file]
fileGzipStats[file] = gzipSize.file(file)
return fileGzipStats[file]
}
export function collectPages(
directory: string,
pageExtensions: string[]
): Promise<string[]> {
return recursiveReadDir(
directory,
new RegExp(`\\.(?:${pageExtensions.join('|')})$`)
)
}
export interface PageInfo {
isAmp?: boolean
isHybridAmp?: boolean
size: number
static: boolean
isSsg: boolean
ssgPageRoutes: string[] | null
serverBundle: string
}
2019-12-12 17:20:24 +01:00
export async function printTreeView(
list: readonly string[],
pageInfos: Map<string, PageInfo>,
2019-12-12 17:20:24 +01:00
serverless: boolean,
{
distPath,
pagesDir,
pageExtensions,
buildManifest,
isModern,
}: {
distPath: string
pagesDir: string
pageExtensions: string[]
buildManifest: BuildManifestShape
isModern: boolean
}
) {
const getPrettySize = (_size: number): string => {
const size = prettyBytes(_size)
2019-12-14 07:39:59 +01:00
// green for 0-130kb
if (_size < 130 * 1000) return chalk.green(size)
// yellow for 130-170kb
if (_size < 170 * 1000) return chalk.yellow(size)
// red for >= 170kb
return chalk.red.bold(size)
}
const messages: [string, string][] = [
['Page', 'Size'].map(entry => chalk.underline(entry)) as [string, string],
]
2019-12-12 17:20:24 +01:00
const hasCustomApp = await findPageFile(pagesDir, '/_app', pageExtensions)
const hasCustomError = await findPageFile(pagesDir, '/_error', pageExtensions)
const pageList = list
.slice()
.filter(
e =>
!(
e === '/_document' ||
(!hasCustomApp && e === '/_app') ||
(!hasCustomError && e === '/_error')
)
)
.sort((a, b) => a.localeCompare(b))
2019-12-12 17:20:24 +01:00
pageList.forEach((item, i, arr) => {
const symbol =
i === 0
? arr.length === 1
? '─'
: '┌'
: i === arr.length - 1
? '└'
: '├'
const pageInfo = pageInfos.get(item)
messages.push([
`${symbol} ${
item === '/_app'
2019-12-12 17:20:24 +01:00
? ' '
: pageInfo && pageInfo.static
? '○'
: pageInfo && pageInfo.isSsg
? '●'
: 'λ'
} ${item}`,
pageInfo
? pageInfo.isAmp
? chalk.cyan('AMP')
: pageInfo.size >= 0
? getPrettySize(pageInfo.size)
: ''
: '',
])
if (pageInfo && pageInfo.ssgPageRoutes && pageInfo.ssgPageRoutes.length) {
const totalRoutes = pageInfo.ssgPageRoutes.length
const previewPages = totalRoutes === 4 ? 4 : 3
const contSymbol = i === arr.length - 1 ? ' ' : '├'
const routes = pageInfo.ssgPageRoutes.slice(0, previewPages)
if (totalRoutes > previewPages) {
const remaining = totalRoutes - previewPages
routes.push(`[+${remaining} more paths]`)
}
2019-12-12 17:20:24 +01:00
routes.forEach((slug, index, { length }) => {
const innerSymbol = index === length - 1 ? '└' : '├'
messages.push([`${contSymbol} ${innerSymbol} ${slug}`, ''])
})
}
})
const sharedData = await getSharedSizes(
distPath,
buildManifest,
isModern,
pageInfos
)
messages.push(['+ shared by all', getPrettySize(sharedData.total)])
Object.keys(sharedData.files)
.sort()
.forEach((fileName, index, { length }) => {
const innerSymbol = index === length - 1 ? '└' : '├'
messages.push([
` ${innerSymbol} ${fileName
.replace(/^static\//, '')
.replace(/[.-][0-9a-z]{20}(?=\.)/, '')}`,
getPrettySize(sharedData.files[fileName]),
])
})
console.log(
textTable(messages, {
align: ['l', 'l'],
stringLength: str => stripAnsi(str).length,
})
)
console.log()
console.log(
textTable(
[
[
'λ',
serverless ? '(Lambda)' : '(Server)',
`server-side renders at runtime (uses ${chalk.cyan(
'getInitialProps'
)} or ${chalk.cyan('getServerProps')})`,
],
[
'○',
'(Static)',
'automatically rendered as static HTML (uses no initial props)',
],
[
'●',
'(SSG)',
`automatically generated as static HTML + JSON (uses ${chalk.cyan(
'getStaticProps'
)})`,
],
] as [string, string, string][],
{
align: ['l', 'l', 'l'],
stringLength: str => stripAnsi(str).length,
}
)
)
console.log()
}
export function printCustomRoutes({
redirects,
rewrites,
}: {
redirects: Redirect[]
rewrites: Rewrite[]
}) {
const printRoutes = (
routes: Redirect[] | Rewrite[],
type: 'Redirects' | 'Rewrites'
) => {
const isRedirects = type === 'Redirects'
console.log(chalk.underline(type))
console.log()
console.log(
textTable(
[
[
'Source',
'Destination',
...(isRedirects ? ['statusCode'] : []),
].map(str => chalk.bold(str)),
...Object.entries(routes).map(([key, route]) => {
return [
route.source,
route.destination,
...(isRedirects
? [
((route as Redirect).statusCode ||
DEFAULT_REDIRECT_STATUS) + '',
]
: []),
]
}),
],
{
align: ['l', 'l', 'l'],
stringLength: str => stripAnsi(str).length,
}
)
)
console.log()
}
if (redirects.length) {
printRoutes(redirects, 'Redirects')
}
if (rewrites.length) {
printRoutes(rewrites, 'Rewrites')
}
}
type BuildManifestShape = { pages: { [k: string]: string[] } }
type ComputeManifestShape = {
commonFiles: string[]
sizeCommonFile: { [file: string]: number }
sizeCommonFiles: number
}
let cachedBuildManifest: BuildManifestShape | undefined
let lastCompute: ComputeManifestShape | undefined
let lastComputeModern: boolean | undefined
let lastComputePageInfo: boolean | undefined
async function computeFromManifest(
manifest: BuildManifestShape,
distPath: string,
isModern: boolean,
pageInfos?: Map<string, PageInfo>
): Promise<ComputeManifestShape> {
if (
Object.is(cachedBuildManifest, manifest) &&
lastComputeModern === isModern &&
lastComputePageInfo === !!pageInfos
) {
return lastCompute!
}
let expected = 0
const files = new Map<string, number>()
Object.keys(manifest.pages).forEach(key => {
if (key === '/_polyfills') {
return
}
if (pageInfos) {
const cleanKey = key.replace(/\/index$/, '') || '/'
const pageInfo = pageInfos.get(cleanKey)
// don't include AMP pages since they don't rely on shared bundles
if (pageInfo?.isHybridAmp || pageInfo?.isAmp) {
return
}
}
++expected
manifest.pages[key].forEach(file => {
if (
// Filter out CSS
!file.endsWith('.js') ||
// Select Modern or Legacy scripts
file.endsWith('.module.js') !== isModern
) {
return
}
if (files.has(file)) {
files.set(file, files.get(file)! + 1)
} else {
files.set(file, 1)
}
})
})
const commonFiles = [...files.entries()]
.filter(([, len]) => len === expected)
.map(([f]) => f)
2019-12-14 07:39:59 +01:00
let stats: [string, number][]
try {
stats = await Promise.all(
commonFiles.map(
async f =>
2019-12-14 07:39:59 +01:00
[f, await fsStatGzip(path.join(distPath, f))] as [string, number]
)
)
} catch (_) {
stats = []
}
lastCompute = {
commonFiles,
sizeCommonFile: stats.reduce(
2019-12-14 07:39:59 +01:00
(obj, n) => Object.assign(obj, { [n[0]]: n[1] }),
{}
),
2019-12-14 07:39:59 +01:00
sizeCommonFiles: stats.reduce((size, [, stat]) => size + stat, 0),
}
cachedBuildManifest = manifest
lastComputeModern = isModern
lastComputePageInfo = !!pageInfos
return lastCompute!
}
function difference<T>(main: T[], sub: T[]): T[] {
const a = new Set(main)
const b = new Set(sub)
return [...a].filter(x => !b.has(x))
}
export async function getSharedSizes(
distPath: string,
buildManifest: BuildManifestShape,
isModern: boolean,
pageInfos: Map<string, PageInfo>
): Promise<{ total: number; files: { [page: string]: number } }> {
const data = await computeFromManifest(
buildManifest,
distPath,
isModern,
pageInfos
)
return { total: data.sizeCommonFiles, files: data.sizeCommonFile }
}
export async function getPageSizeInKb(
page: string,
distPath: string,
buildId: string,
buildManifest: BuildManifestShape,
isModern: boolean
): Promise<number> {
const data = await computeFromManifest(buildManifest, distPath, isModern)
const deps = difference(buildManifest.pages[page] || [], data.commonFiles)
.filter(
entry =>
entry.endsWith('.js') && entry.endsWith('.module.js') === isModern
)
.map(dep => `${distPath}/${dep}`)
const clientBundle = path.join(
distPath,
`static/${buildId}/pages/`,
`${page}${isModern ? '.module' : ''}.js`
)
deps.push(clientBundle)
try {
2019-12-14 07:39:59 +01:00
let depStats = await Promise.all(deps.map(fsStatGzip))
return depStats.reduce((size, stat) => size + stat, 0)
} catch (_) {}
return -1
}
Add experimental SPR support (#8832) * initial commit for SPRv2 * Add initial SPR cache handling * update SPR handling * Implement SPR handling in render * Update tests, handle caching with serverless next start, add TODOs, and update manifest generating * Handle no prerender-manifest from not being used * Fix url.parse error * Apply suggestions from code review Co-Authored-By: Joe Haddad <joe.haddad@zeit.co> * Replace set with constants in next-page-config * simplify sprStatus.used * Add error if getStaticProps is used with getInitialProps * Remove stale TODO * Update revalidate values in SPR cache for non-seeded routes * Apply suggestions from code review * Remove concurrency type * Rename variable for clarity * Add copying prerender files during export * Add comment for clarity * Fix exporting * Update comment * Add additional note * Rename variable * Update to not re-export SPR pages from build * Hard navigate when fetching data fails * Remove default extension * Add brackets * Add checking output files to prerender tests * Adjust export move logic * Clarify behavior of export aggregation * Update variable names for clarity * Update tests * Add comment * s/an oxymoron/contradictory/ * rename * Extract error case * Add tests for exporting SPR pages and update /_next/data endpoint to end with .json * Relocate variable * Adjust route building * Rename to unstable * Rename unstable_getStaticParams * Fix linting * Only add this when a data request * Update prerender data tests * s/isServerless/isLikeServerless/ * Don't rely on query for `next start` in serverless mode * Rename var * Update renderedDuringBuild check * Add test for dynamic param with bracket * Fix serverless next start handling * remove todo * Adjust comment * Update calculateRevalidate * Remove cache logic from render.tsx * Remove extra imports * Move SPR cache logic to next-server * Remove old isDynamic prop * Add calling App getInitialProps for SPR pages * Update revalidate logic * Add isStale to SprCacheValue * Update headers for SPR * add awaiting pendingRevalidation * Dont return null for revalidation render * Adjust logic * Be sure to remove coalesced render * Fix data for serverless * Create a method coalescing utility * Remove TODO * Extract send payload helper * Wrap in-line * Move around some code * Add tests for de-duping and revalidating * Update prerender manifest test
2019-09-24 10:50:04 +02:00
export async function isPageStatic(
page: string,
serverBundle: string,
runtimeEnvConfig: any
Add experimental SPR support (#8832) * initial commit for SPRv2 * Add initial SPR cache handling * update SPR handling * Implement SPR handling in render * Update tests, handle caching with serverless next start, add TODOs, and update manifest generating * Handle no prerender-manifest from not being used * Fix url.parse error * Apply suggestions from code review Co-Authored-By: Joe Haddad <joe.haddad@zeit.co> * Replace set with constants in next-page-config * simplify sprStatus.used * Add error if getStaticProps is used with getInitialProps * Remove stale TODO * Update revalidate values in SPR cache for non-seeded routes * Apply suggestions from code review * Remove concurrency type * Rename variable for clarity * Add copying prerender files during export * Add comment for clarity * Fix exporting * Update comment * Add additional note * Rename variable * Update to not re-export SPR pages from build * Hard navigate when fetching data fails * Remove default extension * Add brackets * Add checking output files to prerender tests * Adjust export move logic * Clarify behavior of export aggregation * Update variable names for clarity * Update tests * Add comment * s/an oxymoron/contradictory/ * rename * Extract error case * Add tests for exporting SPR pages and update /_next/data endpoint to end with .json * Relocate variable * Adjust route building * Rename to unstable * Rename unstable_getStaticParams * Fix linting * Only add this when a data request * Update prerender data tests * s/isServerless/isLikeServerless/ * Don't rely on query for `next start` in serverless mode * Rename var * Update renderedDuringBuild check * Add test for dynamic param with bracket * Fix serverless next start handling * remove todo * Adjust comment * Update calculateRevalidate * Remove cache logic from render.tsx * Remove extra imports * Move SPR cache logic to next-server * Remove old isDynamic prop * Add calling App getInitialProps for SPR pages * Update revalidate logic * Add isStale to SprCacheValue * Update headers for SPR * add awaiting pendingRevalidation * Dont return null for revalidation render * Adjust logic * Be sure to remove coalesced render * Fix data for serverless * Create a method coalescing utility * Remove TODO * Extract send payload helper * Wrap in-line * Move around some code * Add tests for de-duping and revalidating * Update prerender manifest test
2019-09-24 10:50:04 +02:00
): Promise<{
static?: boolean
prerender?: boolean
isHybridAmp?: boolean
prerenderRoutes?: string[] | undefined
}> {
try {
require('../next-server/lib/runtime-config').setConfig(runtimeEnvConfig)
const mod = require(serverBundle)
const Comp = mod.default || mod
if (!Comp || !isValidElementType(Comp) || typeof Comp === 'string') {
throw new Error('INVALID_DEFAULT_EXPORT')
}
Add experimental SPR support (#8832) * initial commit for SPRv2 * Add initial SPR cache handling * update SPR handling * Implement SPR handling in render * Update tests, handle caching with serverless next start, add TODOs, and update manifest generating * Handle no prerender-manifest from not being used * Fix url.parse error * Apply suggestions from code review Co-Authored-By: Joe Haddad <joe.haddad@zeit.co> * Replace set with constants in next-page-config * simplify sprStatus.used * Add error if getStaticProps is used with getInitialProps * Remove stale TODO * Update revalidate values in SPR cache for non-seeded routes * Apply suggestions from code review * Remove concurrency type * Rename variable for clarity * Add copying prerender files during export * Add comment for clarity * Fix exporting * Update comment * Add additional note * Rename variable * Update to not re-export SPR pages from build * Hard navigate when fetching data fails * Remove default extension * Add brackets * Add checking output files to prerender tests * Adjust export move logic * Clarify behavior of export aggregation * Update variable names for clarity * Update tests * Add comment * s/an oxymoron/contradictory/ * rename * Extract error case * Add tests for exporting SPR pages and update /_next/data endpoint to end with .json * Relocate variable * Adjust route building * Rename to unstable * Rename unstable_getStaticParams * Fix linting * Only add this when a data request * Update prerender data tests * s/isServerless/isLikeServerless/ * Don't rely on query for `next start` in serverless mode * Rename var * Update renderedDuringBuild check * Add test for dynamic param with bracket * Fix serverless next start handling * remove todo * Adjust comment * Update calculateRevalidate * Remove cache logic from render.tsx * Remove extra imports * Move SPR cache logic to next-server * Remove old isDynamic prop * Add calling App getInitialProps for SPR pages * Update revalidate logic * Add isStale to SprCacheValue * Update headers for SPR * add awaiting pendingRevalidation * Dont return null for revalidation render * Adjust logic * Be sure to remove coalesced render * Fix data for serverless * Create a method coalescing utility * Remove TODO * Extract send payload helper * Wrap in-line * Move around some code * Add tests for de-duping and revalidating * Update prerender manifest test
2019-09-24 10:50:04 +02:00
const hasGetInitialProps = !!(Comp as any).getInitialProps
const hasStaticProps = !!mod.unstable_getStaticProps
const hasStaticPaths = !!mod.unstable_getStaticPaths
const hasLegacyStaticParams = !!mod.unstable_getStaticParams
if (hasLegacyStaticParams) {
throw new Error(
`unstable_getStaticParams was replaced with unstable_getStaticPaths. Please update your code.`
)
}
Add experimental SPR support (#8832) * initial commit for SPRv2 * Add initial SPR cache handling * update SPR handling * Implement SPR handling in render * Update tests, handle caching with serverless next start, add TODOs, and update manifest generating * Handle no prerender-manifest from not being used * Fix url.parse error * Apply suggestions from code review Co-Authored-By: Joe Haddad <joe.haddad@zeit.co> * Replace set with constants in next-page-config * simplify sprStatus.used * Add error if getStaticProps is used with getInitialProps * Remove stale TODO * Update revalidate values in SPR cache for non-seeded routes * Apply suggestions from code review * Remove concurrency type * Rename variable for clarity * Add copying prerender files during export * Add comment for clarity * Fix exporting * Update comment * Add additional note * Rename variable * Update to not re-export SPR pages from build * Hard navigate when fetching data fails * Remove default extension * Add brackets * Add checking output files to prerender tests * Adjust export move logic * Clarify behavior of export aggregation * Update variable names for clarity * Update tests * Add comment * s/an oxymoron/contradictory/ * rename * Extract error case * Add tests for exporting SPR pages and update /_next/data endpoint to end with .json * Relocate variable * Adjust route building * Rename to unstable * Rename unstable_getStaticParams * Fix linting * Only add this when a data request * Update prerender data tests * s/isServerless/isLikeServerless/ * Don't rely on query for `next start` in serverless mode * Rename var * Update renderedDuringBuild check * Add test for dynamic param with bracket * Fix serverless next start handling * remove todo * Adjust comment * Update calculateRevalidate * Remove cache logic from render.tsx * Remove extra imports * Move SPR cache logic to next-server * Remove old isDynamic prop * Add calling App getInitialProps for SPR pages * Update revalidate logic * Add isStale to SprCacheValue * Update headers for SPR * add awaiting pendingRevalidation * Dont return null for revalidation render * Adjust logic * Be sure to remove coalesced render * Fix data for serverless * Create a method coalescing utility * Remove TODO * Extract send payload helper * Wrap in-line * Move around some code * Add tests for de-duping and revalidating * Update prerender manifest test
2019-09-24 10:50:04 +02:00
// A page cannot be prerendered _and_ define a data requirement. That's
// contradictory!
if (hasGetInitialProps && hasStaticProps) {
throw new Error(SPR_GET_INITIAL_PROPS_CONFLICT)
}
// A page cannot have static parameters if it is not a dynamic page.
if (hasStaticProps && hasStaticPaths && !isDynamicRoute(page)) {
Add experimental SPR support (#8832) * initial commit for SPRv2 * Add initial SPR cache handling * update SPR handling * Implement SPR handling in render * Update tests, handle caching with serverless next start, add TODOs, and update manifest generating * Handle no prerender-manifest from not being used * Fix url.parse error * Apply suggestions from code review Co-Authored-By: Joe Haddad <joe.haddad@zeit.co> * Replace set with constants in next-page-config * simplify sprStatus.used * Add error if getStaticProps is used with getInitialProps * Remove stale TODO * Update revalidate values in SPR cache for non-seeded routes * Apply suggestions from code review * Remove concurrency type * Rename variable for clarity * Add copying prerender files during export * Add comment for clarity * Fix exporting * Update comment * Add additional note * Rename variable * Update to not re-export SPR pages from build * Hard navigate when fetching data fails * Remove default extension * Add brackets * Add checking output files to prerender tests * Adjust export move logic * Clarify behavior of export aggregation * Update variable names for clarity * Update tests * Add comment * s/an oxymoron/contradictory/ * rename * Extract error case * Add tests for exporting SPR pages and update /_next/data endpoint to end with .json * Relocate variable * Adjust route building * Rename to unstable * Rename unstable_getStaticParams * Fix linting * Only add this when a data request * Update prerender data tests * s/isServerless/isLikeServerless/ * Don't rely on query for `next start` in serverless mode * Rename var * Update renderedDuringBuild check * Add test for dynamic param with bracket * Fix serverless next start handling * remove todo * Adjust comment * Update calculateRevalidate * Remove cache logic from render.tsx * Remove extra imports * Move SPR cache logic to next-server * Remove old isDynamic prop * Add calling App getInitialProps for SPR pages * Update revalidate logic * Add isStale to SprCacheValue * Update headers for SPR * add awaiting pendingRevalidation * Dont return null for revalidation render * Adjust logic * Be sure to remove coalesced render * Fix data for serverless * Create a method coalescing utility * Remove TODO * Extract send payload helper * Wrap in-line * Move around some code * Add tests for de-duping and revalidating * Update prerender manifest test
2019-09-24 10:50:04 +02:00
throw new Error(
`unstable_getStaticPaths can only be used with dynamic pages. https://nextjs.org/docs#dynamic-routing`
Add experimental SPR support (#8832) * initial commit for SPRv2 * Add initial SPR cache handling * update SPR handling * Implement SPR handling in render * Update tests, handle caching with serverless next start, add TODOs, and update manifest generating * Handle no prerender-manifest from not being used * Fix url.parse error * Apply suggestions from code review Co-Authored-By: Joe Haddad <joe.haddad@zeit.co> * Replace set with constants in next-page-config * simplify sprStatus.used * Add error if getStaticProps is used with getInitialProps * Remove stale TODO * Update revalidate values in SPR cache for non-seeded routes * Apply suggestions from code review * Remove concurrency type * Rename variable for clarity * Add copying prerender files during export * Add comment for clarity * Fix exporting * Update comment * Add additional note * Rename variable * Update to not re-export SPR pages from build * Hard navigate when fetching data fails * Remove default extension * Add brackets * Add checking output files to prerender tests * Adjust export move logic * Clarify behavior of export aggregation * Update variable names for clarity * Update tests * Add comment * s/an oxymoron/contradictory/ * rename * Extract error case * Add tests for exporting SPR pages and update /_next/data endpoint to end with .json * Relocate variable * Adjust route building * Rename to unstable * Rename unstable_getStaticParams * Fix linting * Only add this when a data request * Update prerender data tests * s/isServerless/isLikeServerless/ * Don't rely on query for `next start` in serverless mode * Rename var * Update renderedDuringBuild check * Add test for dynamic param with bracket * Fix serverless next start handling * remove todo * Adjust comment * Update calculateRevalidate * Remove cache logic from render.tsx * Remove extra imports * Move SPR cache logic to next-server * Remove old isDynamic prop * Add calling App getInitialProps for SPR pages * Update revalidate logic * Add isStale to SprCacheValue * Update headers for SPR * add awaiting pendingRevalidation * Dont return null for revalidation render * Adjust logic * Be sure to remove coalesced render * Fix data for serverless * Create a method coalescing utility * Remove TODO * Extract send payload helper * Wrap in-line * Move around some code * Add tests for de-duping and revalidating * Update prerender manifest test
2019-09-24 10:50:04 +02:00
)
}
let prerenderPaths: string[] | undefined
if (hasStaticProps && hasStaticPaths) {
Add experimental SPR support (#8832) * initial commit for SPRv2 * Add initial SPR cache handling * update SPR handling * Implement SPR handling in render * Update tests, handle caching with serverless next start, add TODOs, and update manifest generating * Handle no prerender-manifest from not being used * Fix url.parse error * Apply suggestions from code review Co-Authored-By: Joe Haddad <joe.haddad@zeit.co> * Replace set with constants in next-page-config * simplify sprStatus.used * Add error if getStaticProps is used with getInitialProps * Remove stale TODO * Update revalidate values in SPR cache for non-seeded routes * Apply suggestions from code review * Remove concurrency type * Rename variable for clarity * Add copying prerender files during export * Add comment for clarity * Fix exporting * Update comment * Add additional note * Rename variable * Update to not re-export SPR pages from build * Hard navigate when fetching data fails * Remove default extension * Add brackets * Add checking output files to prerender tests * Adjust export move logic * Clarify behavior of export aggregation * Update variable names for clarity * Update tests * Add comment * s/an oxymoron/contradictory/ * rename * Extract error case * Add tests for exporting SPR pages and update /_next/data endpoint to end with .json * Relocate variable * Adjust route building * Rename to unstable * Rename unstable_getStaticParams * Fix linting * Only add this when a data request * Update prerender data tests * s/isServerless/isLikeServerless/ * Don't rely on query for `next start` in serverless mode * Rename var * Update renderedDuringBuild check * Add test for dynamic param with bracket * Fix serverless next start handling * remove todo * Adjust comment * Update calculateRevalidate * Remove cache logic from render.tsx * Remove extra imports * Move SPR cache logic to next-server * Remove old isDynamic prop * Add calling App getInitialProps for SPR pages * Update revalidate logic * Add isStale to SprCacheValue * Update headers for SPR * add awaiting pendingRevalidation * Dont return null for revalidation render * Adjust logic * Be sure to remove coalesced render * Fix data for serverless * Create a method coalescing utility * Remove TODO * Extract send payload helper * Wrap in-line * Move around some code * Add tests for de-duping and revalidating * Update prerender manifest test
2019-09-24 10:50:04 +02:00
prerenderPaths = [] as string[]
const _routeMatcher = getRouteMatcher(getRouteRegex(page))
Add experimental SPR support (#8832) * initial commit for SPRv2 * Add initial SPR cache handling * update SPR handling * Implement SPR handling in render * Update tests, handle caching with serverless next start, add TODOs, and update manifest generating * Handle no prerender-manifest from not being used * Fix url.parse error * Apply suggestions from code review Co-Authored-By: Joe Haddad <joe.haddad@zeit.co> * Replace set with constants in next-page-config * simplify sprStatus.used * Add error if getStaticProps is used with getInitialProps * Remove stale TODO * Update revalidate values in SPR cache for non-seeded routes * Apply suggestions from code review * Remove concurrency type * Rename variable for clarity * Add copying prerender files during export * Add comment for clarity * Fix exporting * Update comment * Add additional note * Rename variable * Update to not re-export SPR pages from build * Hard navigate when fetching data fails * Remove default extension * Add brackets * Add checking output files to prerender tests * Adjust export move logic * Clarify behavior of export aggregation * Update variable names for clarity * Update tests * Add comment * s/an oxymoron/contradictory/ * rename * Extract error case * Add tests for exporting SPR pages and update /_next/data endpoint to end with .json * Relocate variable * Adjust route building * Rename to unstable * Rename unstable_getStaticParams * Fix linting * Only add this when a data request * Update prerender data tests * s/isServerless/isLikeServerless/ * Don't rely on query for `next start` in serverless mode * Rename var * Update renderedDuringBuild check * Add test for dynamic param with bracket * Fix serverless next start handling * remove todo * Adjust comment * Update calculateRevalidate * Remove cache logic from render.tsx * Remove extra imports * Move SPR cache logic to next-server * Remove old isDynamic prop * Add calling App getInitialProps for SPR pages * Update revalidate logic * Add isStale to SprCacheValue * Update headers for SPR * add awaiting pendingRevalidation * Dont return null for revalidation render * Adjust logic * Be sure to remove coalesced render * Fix data for serverless * Create a method coalescing utility * Remove TODO * Extract send payload helper * Wrap in-line * Move around some code * Add tests for de-duping and revalidating * Update prerender manifest test
2019-09-24 10:50:04 +02:00
// Get the default list of allowed params.
const _validParamKeys = Object.keys(_routeMatcher(page))
const toPrerender: Array<
{ params?: { [key: string]: string } } | string
> = await mod.unstable_getStaticPaths()
Add experimental SPR support (#8832) * initial commit for SPRv2 * Add initial SPR cache handling * update SPR handling * Implement SPR handling in render * Update tests, handle caching with serverless next start, add TODOs, and update manifest generating * Handle no prerender-manifest from not being used * Fix url.parse error * Apply suggestions from code review Co-Authored-By: Joe Haddad <joe.haddad@zeit.co> * Replace set with constants in next-page-config * simplify sprStatus.used * Add error if getStaticProps is used with getInitialProps * Remove stale TODO * Update revalidate values in SPR cache for non-seeded routes * Apply suggestions from code review * Remove concurrency type * Rename variable for clarity * Add copying prerender files during export * Add comment for clarity * Fix exporting * Update comment * Add additional note * Rename variable * Update to not re-export SPR pages from build * Hard navigate when fetching data fails * Remove default extension * Add brackets * Add checking output files to prerender tests * Adjust export move logic * Clarify behavior of export aggregation * Update variable names for clarity * Update tests * Add comment * s/an oxymoron/contradictory/ * rename * Extract error case * Add tests for exporting SPR pages and update /_next/data endpoint to end with .json * Relocate variable * Adjust route building * Rename to unstable * Rename unstable_getStaticParams * Fix linting * Only add this when a data request * Update prerender data tests * s/isServerless/isLikeServerless/ * Don't rely on query for `next start` in serverless mode * Rename var * Update renderedDuringBuild check * Add test for dynamic param with bracket * Fix serverless next start handling * remove todo * Adjust comment * Update calculateRevalidate * Remove cache logic from render.tsx * Remove extra imports * Move SPR cache logic to next-server * Remove old isDynamic prop * Add calling App getInitialProps for SPR pages * Update revalidate logic * Add isStale to SprCacheValue * Update headers for SPR * add awaiting pendingRevalidation * Dont return null for revalidation render * Adjust logic * Be sure to remove coalesced render * Fix data for serverless * Create a method coalescing utility * Remove TODO * Extract send payload helper * Wrap in-line * Move around some code * Add tests for de-duping and revalidating * Update prerender manifest test
2019-09-24 10:50:04 +02:00
toPrerender.forEach(entry => {
// For a string-provided path, we must make sure it matches the dynamic
// route.
if (typeof entry === 'string') {
const result = _routeMatcher(entry)
if (!result) {
throw new Error(
`The provided path \`${entry}\` does not match the page: \`${page}\`.`
)
}
prerenderPaths!.push(entry)
}
// For the object-provided path, we must make sure it specifies all
// required keys.
else {
const invalidKeys = Object.keys(entry).filter(key => key !== 'params')
if (invalidKeys.length) {
throw new Error(
`Additional keys were returned from \`unstable_getStaticPaths\` in page "${page}". ` +
`URL Parameters intended for this dynamic route must be nested under the \`params\` key, i.e.:` +
`\n\n\treturn { params: { ${_validParamKeys
.map(k => `${k}: ...`)
.join(', ')} } }` +
`\n\nKeys that need to be moved: ${invalidKeys.join(', ')}.\n`
)
}
const { params = {} } = entry
Add experimental SPR support (#8832) * initial commit for SPRv2 * Add initial SPR cache handling * update SPR handling * Implement SPR handling in render * Update tests, handle caching with serverless next start, add TODOs, and update manifest generating * Handle no prerender-manifest from not being used * Fix url.parse error * Apply suggestions from code review Co-Authored-By: Joe Haddad <joe.haddad@zeit.co> * Replace set with constants in next-page-config * simplify sprStatus.used * Add error if getStaticProps is used with getInitialProps * Remove stale TODO * Update revalidate values in SPR cache for non-seeded routes * Apply suggestions from code review * Remove concurrency type * Rename variable for clarity * Add copying prerender files during export * Add comment for clarity * Fix exporting * Update comment * Add additional note * Rename variable * Update to not re-export SPR pages from build * Hard navigate when fetching data fails * Remove default extension * Add brackets * Add checking output files to prerender tests * Adjust export move logic * Clarify behavior of export aggregation * Update variable names for clarity * Update tests * Add comment * s/an oxymoron/contradictory/ * rename * Extract error case * Add tests for exporting SPR pages and update /_next/data endpoint to end with .json * Relocate variable * Adjust route building * Rename to unstable * Rename unstable_getStaticParams * Fix linting * Only add this when a data request * Update prerender data tests * s/isServerless/isLikeServerless/ * Don't rely on query for `next start` in serverless mode * Rename var * Update renderedDuringBuild check * Add test for dynamic param with bracket * Fix serverless next start handling * remove todo * Adjust comment * Update calculateRevalidate * Remove cache logic from render.tsx * Remove extra imports * Move SPR cache logic to next-server * Remove old isDynamic prop * Add calling App getInitialProps for SPR pages * Update revalidate logic * Add isStale to SprCacheValue * Update headers for SPR * add awaiting pendingRevalidation * Dont return null for revalidation render * Adjust logic * Be sure to remove coalesced render * Fix data for serverless * Create a method coalescing utility * Remove TODO * Extract send payload helper * Wrap in-line * Move around some code * Add tests for de-duping and revalidating * Update prerender manifest test
2019-09-24 10:50:04 +02:00
let builtPage = page
_validParamKeys.forEach(validParamKey => {
if (typeof params[validParamKey] !== 'string') {
Add experimental SPR support (#8832) * initial commit for SPRv2 * Add initial SPR cache handling * update SPR handling * Implement SPR handling in render * Update tests, handle caching with serverless next start, add TODOs, and update manifest generating * Handle no prerender-manifest from not being used * Fix url.parse error * Apply suggestions from code review Co-Authored-By: Joe Haddad <joe.haddad@zeit.co> * Replace set with constants in next-page-config * simplify sprStatus.used * Add error if getStaticProps is used with getInitialProps * Remove stale TODO * Update revalidate values in SPR cache for non-seeded routes * Apply suggestions from code review * Remove concurrency type * Rename variable for clarity * Add copying prerender files during export * Add comment for clarity * Fix exporting * Update comment * Add additional note * Rename variable * Update to not re-export SPR pages from build * Hard navigate when fetching data fails * Remove default extension * Add brackets * Add checking output files to prerender tests * Adjust export move logic * Clarify behavior of export aggregation * Update variable names for clarity * Update tests * Add comment * s/an oxymoron/contradictory/ * rename * Extract error case * Add tests for exporting SPR pages and update /_next/data endpoint to end with .json * Relocate variable * Adjust route building * Rename to unstable * Rename unstable_getStaticParams * Fix linting * Only add this when a data request * Update prerender data tests * s/isServerless/isLikeServerless/ * Don't rely on query for `next start` in serverless mode * Rename var * Update renderedDuringBuild check * Add test for dynamic param with bracket * Fix serverless next start handling * remove todo * Adjust comment * Update calculateRevalidate * Remove cache logic from render.tsx * Remove extra imports * Move SPR cache logic to next-server * Remove old isDynamic prop * Add calling App getInitialProps for SPR pages * Update revalidate logic * Add isStale to SprCacheValue * Update headers for SPR * add awaiting pendingRevalidation * Dont return null for revalidation render * Adjust logic * Be sure to remove coalesced render * Fix data for serverless * Create a method coalescing utility * Remove TODO * Extract send payload helper * Wrap in-line * Move around some code * Add tests for de-duping and revalidating * Update prerender manifest test
2019-09-24 10:50:04 +02:00
throw new Error(
`A required parameter (${validParamKey}) was not provided as a string.`
)
}
builtPage = builtPage.replace(
`[${validParamKey}]`,
encodeURIComponent(params[validParamKey])
Add experimental SPR support (#8832) * initial commit for SPRv2 * Add initial SPR cache handling * update SPR handling * Implement SPR handling in render * Update tests, handle caching with serverless next start, add TODOs, and update manifest generating * Handle no prerender-manifest from not being used * Fix url.parse error * Apply suggestions from code review Co-Authored-By: Joe Haddad <joe.haddad@zeit.co> * Replace set with constants in next-page-config * simplify sprStatus.used * Add error if getStaticProps is used with getInitialProps * Remove stale TODO * Update revalidate values in SPR cache for non-seeded routes * Apply suggestions from code review * Remove concurrency type * Rename variable for clarity * Add copying prerender files during export * Add comment for clarity * Fix exporting * Update comment * Add additional note * Rename variable * Update to not re-export SPR pages from build * Hard navigate when fetching data fails * Remove default extension * Add brackets * Add checking output files to prerender tests * Adjust export move logic * Clarify behavior of export aggregation * Update variable names for clarity * Update tests * Add comment * s/an oxymoron/contradictory/ * rename * Extract error case * Add tests for exporting SPR pages and update /_next/data endpoint to end with .json * Relocate variable * Adjust route building * Rename to unstable * Rename unstable_getStaticParams * Fix linting * Only add this when a data request * Update prerender data tests * s/isServerless/isLikeServerless/ * Don't rely on query for `next start` in serverless mode * Rename var * Update renderedDuringBuild check * Add test for dynamic param with bracket * Fix serverless next start handling * remove todo * Adjust comment * Update calculateRevalidate * Remove cache logic from render.tsx * Remove extra imports * Move SPR cache logic to next-server * Remove old isDynamic prop * Add calling App getInitialProps for SPR pages * Update revalidate logic * Add isStale to SprCacheValue * Update headers for SPR * add awaiting pendingRevalidation * Dont return null for revalidation render * Adjust logic * Be sure to remove coalesced render * Fix data for serverless * Create a method coalescing utility * Remove TODO * Extract send payload helper * Wrap in-line * Move around some code * Add tests for de-duping and revalidating * Update prerender manifest test
2019-09-24 10:50:04 +02:00
)
})
prerenderPaths!.push(builtPage)
}
})
}
const config = mod.config || {}
return {
Add experimental SPR support (#8832) * initial commit for SPRv2 * Add initial SPR cache handling * update SPR handling * Implement SPR handling in render * Update tests, handle caching with serverless next start, add TODOs, and update manifest generating * Handle no prerender-manifest from not being used * Fix url.parse error * Apply suggestions from code review Co-Authored-By: Joe Haddad <joe.haddad@zeit.co> * Replace set with constants in next-page-config * simplify sprStatus.used * Add error if getStaticProps is used with getInitialProps * Remove stale TODO * Update revalidate values in SPR cache for non-seeded routes * Apply suggestions from code review * Remove concurrency type * Rename variable for clarity * Add copying prerender files during export * Add comment for clarity * Fix exporting * Update comment * Add additional note * Rename variable * Update to not re-export SPR pages from build * Hard navigate when fetching data fails * Remove default extension * Add brackets * Add checking output files to prerender tests * Adjust export move logic * Clarify behavior of export aggregation * Update variable names for clarity * Update tests * Add comment * s/an oxymoron/contradictory/ * rename * Extract error case * Add tests for exporting SPR pages and update /_next/data endpoint to end with .json * Relocate variable * Adjust route building * Rename to unstable * Rename unstable_getStaticParams * Fix linting * Only add this when a data request * Update prerender data tests * s/isServerless/isLikeServerless/ * Don't rely on query for `next start` in serverless mode * Rename var * Update renderedDuringBuild check * Add test for dynamic param with bracket * Fix serverless next start handling * remove todo * Adjust comment * Update calculateRevalidate * Remove cache logic from render.tsx * Remove extra imports * Move SPR cache logic to next-server * Remove old isDynamic prop * Add calling App getInitialProps for SPR pages * Update revalidate logic * Add isStale to SprCacheValue * Update headers for SPR * add awaiting pendingRevalidation * Dont return null for revalidation render * Adjust logic * Be sure to remove coalesced render * Fix data for serverless * Create a method coalescing utility * Remove TODO * Extract send payload helper * Wrap in-line * Move around some code * Add tests for de-duping and revalidating * Update prerender manifest test
2019-09-24 10:50:04 +02:00
static: !hasStaticProps && !hasGetInitialProps,
isHybridAmp: config.amp === 'hybrid',
Add experimental SPR support (#8832) * initial commit for SPRv2 * Add initial SPR cache handling * update SPR handling * Implement SPR handling in render * Update tests, handle caching with serverless next start, add TODOs, and update manifest generating * Handle no prerender-manifest from not being used * Fix url.parse error * Apply suggestions from code review Co-Authored-By: Joe Haddad <joe.haddad@zeit.co> * Replace set with constants in next-page-config * simplify sprStatus.used * Add error if getStaticProps is used with getInitialProps * Remove stale TODO * Update revalidate values in SPR cache for non-seeded routes * Apply suggestions from code review * Remove concurrency type * Rename variable for clarity * Add copying prerender files during export * Add comment for clarity * Fix exporting * Update comment * Add additional note * Rename variable * Update to not re-export SPR pages from build * Hard navigate when fetching data fails * Remove default extension * Add brackets * Add checking output files to prerender tests * Adjust export move logic * Clarify behavior of export aggregation * Update variable names for clarity * Update tests * Add comment * s/an oxymoron/contradictory/ * rename * Extract error case * Add tests for exporting SPR pages and update /_next/data endpoint to end with .json * Relocate variable * Adjust route building * Rename to unstable * Rename unstable_getStaticParams * Fix linting * Only add this when a data request * Update prerender data tests * s/isServerless/isLikeServerless/ * Don't rely on query for `next start` in serverless mode * Rename var * Update renderedDuringBuild check * Add test for dynamic param with bracket * Fix serverless next start handling * remove todo * Adjust comment * Update calculateRevalidate * Remove cache logic from render.tsx * Remove extra imports * Move SPR cache logic to next-server * Remove old isDynamic prop * Add calling App getInitialProps for SPR pages * Update revalidate logic * Add isStale to SprCacheValue * Update headers for SPR * add awaiting pendingRevalidation * Dont return null for revalidation render * Adjust logic * Be sure to remove coalesced render * Fix data for serverless * Create a method coalescing utility * Remove TODO * Extract send payload helper * Wrap in-line * Move around some code * Add tests for de-duping and revalidating * Update prerender manifest test
2019-09-24 10:50:04 +02:00
prerenderRoutes: prerenderPaths,
prerender: hasStaticProps,
}
} catch (err) {
if (err.code === 'MODULE_NOT_FOUND') return {}
throw err
}
}
export function hasCustomAppGetInitialProps(
_appBundle: string,
runtimeEnvConfig: any
): boolean {
require('../next-server/lib/runtime-config').setConfig(runtimeEnvConfig)
let mod = require(_appBundle)
if (_appBundle.endsWith('_app.js')) {
mod = mod.default || mod
} else {
// since we don't output _app in serverless mode get it from a page
mod = mod._app
}
return mod.getInitialProps !== mod.origGetInitialProps
}