Update to leverage AsyncLocalStorage for app static handling (#40727)
Leverages `AsyncLocalStorage` when available for handling static generation context and falls back to requiring render to be isolated when `AsyncLocalStorage` is not available. Note: most changes are spacing so toggling to ignore spacing may make reviewing easier
This commit is contained in:
parent
4719517381
commit
bbeaf081ae
4 changed files with 711 additions and 658 deletions
|
@ -33,7 +33,6 @@ export const CONTEXT_NAMES = {
|
|||
HeadersContext: 'HeadersContext',
|
||||
PreviewDataContext: 'PreviewDataContext',
|
||||
CookiesContext: 'CookiesContext',
|
||||
StaticGenerationContext: 'StaticGenerationContext',
|
||||
FetchRevalidateContext: 'FetchRevalidateContext',
|
||||
} as const
|
||||
|
||||
|
@ -42,7 +41,3 @@ export const PreviewDataContext = createContext(
|
|||
CONTEXT_NAMES.PreviewDataContext
|
||||
)
|
||||
export const CookiesContext = createContext(CONTEXT_NAMES.CookiesContext)
|
||||
export const StaticGenerationContext = createContext(
|
||||
CONTEXT_NAMES.StaticGenerationContext,
|
||||
{ isStaticGeneration: false }
|
||||
)
|
||||
|
|
|
@ -1,24 +1,40 @@
|
|||
import type { AsyncLocalStorage } from 'async_hooks'
|
||||
import { useContext } from 'react'
|
||||
import {
|
||||
HeadersContext,
|
||||
PreviewDataContext,
|
||||
CookiesContext,
|
||||
DynamicServerError,
|
||||
StaticGenerationContext,
|
||||
} from './hooks-server-context'
|
||||
|
||||
export function useTrackStaticGeneration() {
|
||||
return useContext<
|
||||
typeof import('./hooks-server-context').StaticGenerationContext
|
||||
>(StaticGenerationContext)
|
||||
export interface StaticGenerationStore {
|
||||
inUse?: boolean
|
||||
pathname?: string
|
||||
revalidate?: number
|
||||
fetchRevalidate?: number
|
||||
isStaticGeneration?: boolean
|
||||
}
|
||||
|
||||
export let staticGenerationAsyncStorage:
|
||||
| AsyncLocalStorage<StaticGenerationStore>
|
||||
| StaticGenerationStore = {}
|
||||
|
||||
if (process.env.NEXT_RUNTIME !== 'edge' && typeof window === 'undefined') {
|
||||
staticGenerationAsyncStorage =
|
||||
new (require('async_hooks').AsyncLocalStorage)()
|
||||
}
|
||||
|
||||
function useStaticGenerationBailout(reason: string) {
|
||||
const staticGenerationContext = useTrackStaticGeneration()
|
||||
const staticGenerationStore =
|
||||
staticGenerationAsyncStorage && 'getStore' in staticGenerationAsyncStorage
|
||||
? staticGenerationAsyncStorage?.getStore()
|
||||
: staticGenerationAsyncStorage
|
||||
|
||||
if (staticGenerationContext.isStaticGeneration) {
|
||||
if (staticGenerationStore?.isStaticGeneration) {
|
||||
// TODO: honor the dynamic: 'force-static'
|
||||
staticGenerationContext.revalidate = 0
|
||||
if (staticGenerationStore) {
|
||||
staticGenerationStore.revalidate = 0
|
||||
}
|
||||
throw new DynamicServerError(reason)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import RenderResult from '../server/render-result'
|
|||
import isError from '../lib/is-error'
|
||||
import { addRequestMeta } from '../server/request-meta'
|
||||
import { normalizeAppPath } from '../shared/lib/router/utils/app-paths'
|
||||
import { REDIRECT_ERROR_CODE } from '../client/components/redirect'
|
||||
|
||||
loadRequireHook()
|
||||
const envConfig = require('../shared/lib/runtime-config')
|
||||
|
@ -419,7 +420,10 @@ export default async function exportPage({
|
|||
)
|
||||
}
|
||||
} catch (err) {
|
||||
if (!(err instanceof DynamicServerError)) {
|
||||
if (
|
||||
!(err instanceof DynamicServerError) &&
|
||||
(err as any).code !== REDIRECT_ERROR_CODE
|
||||
) {
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue