Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Freeze loaded manifests #64313

Merged
merged 1 commit into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 15 additions & 13 deletions packages/next/src/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ import { buildCustomRoute } from '../lib/build-custom-route'
import { createProgress } from './progress'
import { traceMemoryUsage } from '../lib/memory/trace'
import { generateEncryptionKeyBase64 } from '../server/app-render/encryption-utils'
import type { DeepReadonly } from '../shared/lib/deep-readonly'

interface ExperimentalBypassForInfo {
experimentalBypassFor?: RouteHas[]
Expand Down Expand Up @@ -337,27 +338,28 @@ async function readManifest<T extends object>(filePath: string): Promise<T> {

async function writePrerenderManifest(
distDir: string,
manifest: Readonly<PrerenderManifest>
manifest: DeepReadonly<PrerenderManifest>
): Promise<void> {
await writeManifest(path.join(distDir, PRERENDER_MANIFEST), manifest)
await writeEdgePartialPrerenderManifest(distDir, manifest)
}

async function writeEdgePartialPrerenderManifest(
distDir: string,
manifest: Readonly<Partial<PrerenderManifest>>
manifest: DeepReadonly<Partial<PrerenderManifest>>
): Promise<void> {
// We need to write a partial prerender manifest to make preview mode settings available in edge middleware.
// Use env vars in JS bundle and inject the actual vars to edge manifest.
const edgePartialPrerenderManifest: Partial<PrerenderManifest> = {
...manifest,
preview: {
previewModeId: 'process.env.__NEXT_PREVIEW_MODE_ID',
previewModeSigningKey: 'process.env.__NEXT_PREVIEW_MODE_SIGNING_KEY',
previewModeEncryptionKey:
'process.env.__NEXT_PREVIEW_MODE_ENCRYPTION_KEY',
},
}
const edgePartialPrerenderManifest: DeepReadonly<Partial<PrerenderManifest>> =
{
...manifest,
preview: {
previewModeId: 'process.env.__NEXT_PREVIEW_MODE_ID',
previewModeSigningKey: 'process.env.__NEXT_PREVIEW_MODE_SIGNING_KEY',
previewModeEncryptionKey:
'process.env.__NEXT_PREVIEW_MODE_ENCRYPTION_KEY',
},
}
await writeFileUtf8(
path.join(distDir, PRERENDER_MANIFEST.replace(/\.json$/, '.js')),
`self.__PRERENDER_MANIFEST=${JSON.stringify(
Expand All @@ -367,7 +369,7 @@ async function writeEdgePartialPrerenderManifest(
}

async function writeClientSsgManifest(
prerenderManifest: PrerenderManifest,
prerenderManifest: DeepReadonly<PrerenderManifest>,
{
buildId,
distDir,
Expand Down Expand Up @@ -3318,7 +3320,7 @@ export default async function build(
NextBuildContext.allowedRevalidateHeaderKeys =
config.experimental.allowedRevalidateHeaderKeys

const prerenderManifest: Readonly<PrerenderManifest> = {
const prerenderManifest: DeepReadonly<PrerenderManifest> = {
version: 4,
routes: finalPrerenderRoutes,
dynamicRoutes: finalDynamicRoutes,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import type { SizeLimit } from '../../../../../types'
import { internal_getCurrentFunctionWaitUntil } from '../../../../server/web/internal-edge-wait-until'
import type { PAGE_TYPES } from '../../../../lib/page-types'
import type { NextRequestHint } from '../../../../server/web/adapter'
import type { DeepReadonly } from '../../../../shared/lib/deep-readonly'

export function getRender({
dev,
Expand Down Expand Up @@ -53,7 +54,7 @@ export function getRender({
renderToHTML?: any
Document: DocumentType
buildManifest: BuildManifest
prerenderManifest: PrerenderManifest
prerenderManifest: DeepReadonly<PrerenderManifest>
reactLoadableManifest: ReactLoadableManifest
subresourceIntegrityManifest?: Record<string, string>
interceptionRouteRewrites?: ManifestRewriteRoute[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export interface ManifestNode {
}

export type ClientReferenceManifest = {
moduleLoading: {
readonly moduleLoading: {
prefix: string
crossOrigin: string | null
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ import type { ReadonlyHeaders } from '../../server/web/spec-extension/adapters/h
import type { ReadonlyRequestCookies } from '../../server/web/spec-extension/adapters/request-cookies'

import { createAsyncLocalStorage } from './async-local-storage'
import type { DeepReadonly } from '../../shared/lib/deep-readonly'

export interface RequestStore {
readonly headers: ReadonlyHeaders
readonly cookies: ReadonlyRequestCookies
readonly mutableCookies: ResponseCookies
readonly draftMode: DraftModeProvider
readonly reactLoadableManifest: Record<string, { files: string[] }>
readonly reactLoadableManifest: DeepReadonly<
Record<string, { files: string[] }>
>
readonly assetPrefix: string
}

Expand Down
3 changes: 2 additions & 1 deletion packages/next/src/export/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import { formatManifest } from '../build/manifests/formatter/format-manifest'
import { validateRevalidate } from '../server/lib/patch-fetch'
import { TurborepoAccessTraceResult } from '../build/turborepo-access-trace'
import { createProgress } from '../build/progress'
import type { DeepReadonly } from '../shared/lib/deep-readonly'

export class ExportError extends Error {
code = 'NEXT_EXPORT_ERROR'
Expand Down Expand Up @@ -188,7 +189,7 @@ export async function exportAppImpl(
!options.pages &&
(require(join(distDir, SERVER_DIRECTORY, PAGES_MANIFEST)) as PagesManifest)

let prerenderManifest: PrerenderManifest | undefined
let prerenderManifest: DeepReadonly<PrerenderManifest> | undefined
try {
prerenderManifest = require(join(distDir, PRERENDER_MANIFEST))
} catch {}
Expand Down
3 changes: 2 additions & 1 deletion packages/next/src/pages/_document.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
} from '../shared/lib/html-context.shared-runtime'
import type { HtmlProps } from '../shared/lib/html-context.shared-runtime'
import { encodeURIPath } from '../shared/lib/encode-uri-path'
import type { DeepReadonly } from '../shared/lib/deep-readonly'

export type { DocumentContext, DocumentInitialProps, DocumentProps }

Expand Down Expand Up @@ -360,7 +361,7 @@ function getAmpPath(ampPath: string, asPath: string): string {
}

function getNextFontLinkTags(
nextFontManifest: NextFontManifest | undefined,
nextFontManifest: DeepReadonly<NextFontManifest> | undefined,
dangerousAsPath: string,
assetPrefix: string = ''
) {
Expand Down
3 changes: 2 additions & 1 deletion packages/next/src/server/app-render/app-render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ import {
wrapClientComponentLoader,
} from '../client-component-renderer-logger'
import { createServerModuleMap } from './action-utils'
import type { DeepReadonly } from '../../shared/lib/deep-readonly'

export type GetDynamicParamFromSegment = (
// [slug] / [[slug]] / [...slug]
Expand Down Expand Up @@ -137,7 +138,7 @@ export type AppRenderContext = AppRenderBaseContext & {
requestId: string
defaultRevalidate: Revalidate
pagePath: string
clientReferenceManifest: ClientReferenceManifest
clientReferenceManifest: DeepReadonly<ClientReferenceManifest>
assetPrefix: string
flightDataRendererErrorHandler: ErrorHandler
serverComponentsErrorHandler: ErrorHandler
Expand Down
13 changes: 7 additions & 6 deletions packages/next/src/server/app-render/encryption-utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { ActionManifest } from '../../build/webpack/plugins/flight-client-entry-plugin'
import type { ClientReferenceManifest } from '../../build/webpack/plugins/flight-manifest-plugin'
import type { DeepReadonly } from '../../shared/lib/deep-readonly'

// Keep the key in memory as it should never change during the lifetime of the server in
// both development and production.
Expand Down Expand Up @@ -116,8 +117,8 @@ export function setReferenceManifestsSingleton({
serverActionsManifest,
serverModuleMap,
}: {
clientReferenceManifest: ClientReferenceManifest
serverActionsManifest: ActionManifest
clientReferenceManifest: DeepReadonly<ClientReferenceManifest>
serverActionsManifest: DeepReadonly<ActionManifest>
serverModuleMap: {
[id: string]: {
id: string
Expand Down Expand Up @@ -160,8 +161,8 @@ export function getClientReferenceManifestSingleton() {
const serverActionsManifestSingleton = (globalThis as any)[
SERVER_ACTION_MANIFESTS_SINGLETON
] as {
clientReferenceManifest: ClientReferenceManifest
serverActionsManifest: ActionManifest
clientReferenceManifest: DeepReadonly<ClientReferenceManifest>
serverActionsManifest: DeepReadonly<ActionManifest>
}

if (!serverActionsManifestSingleton) {
Expand All @@ -181,8 +182,8 @@ export async function getActionEncryptionKey() {
const serverActionsManifestSingleton = (globalThis as any)[
SERVER_ACTION_MANIFESTS_SINGLETON
] as {
clientReferenceManifest: ClientReferenceManifest
serverActionsManifest: ActionManifest
clientReferenceManifest: DeepReadonly<ClientReferenceManifest>
serverActionsManifest: DeepReadonly<ActionManifest>
}

if (!serverActionsManifestSingleton) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import type { ClientReferenceManifest } from '../../build/webpack/plugins/flight-manifest-plugin'
import type { DeepReadonly } from '../../shared/lib/deep-readonly'

/**
* Get external stylesheet link hrefs based on server CSS manifest.
*/
export function getLinkAndScriptTags(
clientReferenceManifest: ClientReferenceManifest,
clientReferenceManifest: DeepReadonly<ClientReferenceManifest>,
filePath: string,
injectedCSS: Set<string>,
injectedScripts: Set<string>,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { NextFontManifest } from '../../build/webpack/plugins/next-font-manifest-plugin'
import type { DeepReadonly } from '../../shared/lib/deep-readonly'

/**
* Get hrefs for fonts to preload
Expand All @@ -8,7 +9,7 @@ import type { NextFontManifest } from '../../build/webpack/plugins/next-font-man
* Returns null if there are fonts but none to preload and at least some were previously preloaded
*/
export function getPreloadableFonts(
nextFontManifest: NextFontManifest | undefined,
nextFontManifest: DeepReadonly<NextFontManifest> | undefined,
filePath: string | undefined,
injectedFontPreloadTags: Set<string>
): string[] | null {
Expand Down
5 changes: 3 additions & 2 deletions packages/next/src/server/app-render/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type { ParsedUrlQuery } from 'querystring'
import type { AppPageModule } from '../future/route-modules/app-page/module'
import type { SwrDelta } from '../lib/revalidate'
import type { LoadingModuleData } from '../../shared/lib/app-router-context.shared-runtime'
import type { DeepReadonly } from '../../shared/lib/deep-readonly'

import s from 'next/dist/compiled/superstruct'

Expand Down Expand Up @@ -126,14 +127,14 @@ export interface RenderOptsPartial {
buildId: string
basePath: string
trailingSlash: boolean
clientReferenceManifest?: ClientReferenceManifest
clientReferenceManifest?: DeepReadonly<ClientReferenceManifest>
supportsDynamicHTML: boolean
runtime?: ServerRuntime
serverComponents?: boolean
enableTainting?: boolean
assetPrefix?: string
crossOrigin?: '' | 'anonymous' | 'use-credentials' | undefined
nextFontManifest?: NextFontManifest
nextFontManifest?: DeepReadonly<NextFontManifest>
isBot?: boolean
incrementalCache?: import('../lib/incremental-cache').IncrementalCache
isRevalidate?: boolean
Expand Down
3 changes: 2 additions & 1 deletion packages/next/src/server/app-render/use-flight-response.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { ClientReferenceManifest } from '../../build/webpack/plugins/flight
import type { BinaryStreamOf } from './app-render'

import { htmlEscapeJsonString } from '../htmlescape'
import type { DeepReadonly } from '../../shared/lib/deep-readonly'

const isEdgeRuntime = process.env.NEXT_RUNTIME === 'edge'

Expand All @@ -18,7 +19,7 @@ const encoder = new TextEncoder()
*/
export function useFlightStream<T>(
flightStream: BinaryStreamOf<T>,
clientReferenceManifest: ClientReferenceManifest,
clientReferenceManifest: DeepReadonly<ClientReferenceManifest>,
nonce?: string
): Promise<T> {
const response = flightResponses.get(flightStream)
Expand Down
13 changes: 8 additions & 5 deletions packages/next/src/server/base-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ import { NextDataPathnameNormalizer } from './future/normalizers/request/next-da
import { getIsServerAction } from './lib/server-action-request-meta'
import { isInterceptionRouteAppPath } from './future/helpers/interception-routes'
import { toRoute } from './lib/to-route'
import type { DeepReadonly } from '../shared/lib/deep-readonly'

export type FindComponentsResult = {
components: LoadComponentsReturnType
Expand Down Expand Up @@ -285,9 +286,9 @@ export default abstract class Server<ServerOptions extends Options = Options> {
protected readonly renderOpts: BaseRenderOpts
protected readonly serverOptions: Readonly<ServerOptions>
protected readonly appPathRoutes?: Record<string, string[]>
protected readonly clientReferenceManifest?: ClientReferenceManifest
protected readonly clientReferenceManifest?: DeepReadonly<ClientReferenceManifest>
protected interceptionRoutePatterns: RegExp[]
protected nextFontManifest?: NextFontManifest
protected nextFontManifest?: DeepReadonly<NextFontManifest>
private readonly responseCache: ResponseCacheBase

protected abstract getPublicDir(): string
Expand All @@ -314,9 +315,11 @@ export default abstract class Server<ServerOptions extends Options = Options> {
shouldEnsure?: boolean
url?: string
}): Promise<FindComponentsResult | null>
protected abstract getFontManifest(): FontManifest | undefined
protected abstract getPrerenderManifest(): PrerenderManifest
protected abstract getNextFontManifest(): NextFontManifest | undefined
protected abstract getFontManifest(): DeepReadonly<FontManifest> | undefined
protected abstract getPrerenderManifest(): DeepReadonly<PrerenderManifest>
protected abstract getNextFontManifest():
| DeepReadonly<NextFontManifest>
| undefined
protected abstract attachRequestMeta(
req: BaseNextRequest,
parsedUrl: NextUrlWithParsedQuery
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { AppConfig } from '../../../../build/utils'
import type { NextRequest } from '../../../web/spec-extension/request'
import type { PrerenderManifest } from '../../../../build'
import type { NextURL } from '../../../web/next-url'
import type { DeepReadonly } from '../../../../shared/lib/deep-readonly'

import {
RouteModule,
Expand Down Expand Up @@ -63,7 +64,7 @@ export type AppRouteModule =
*/
export interface AppRouteRouteHandlerContext extends RouteModuleHandleContext {
renderOpts: StaticGenerationContext['renderOpts']
prerenderManifest: PrerenderManifest
prerenderManifest: DeepReadonly<PrerenderManifest>
}

/**
Expand Down
5 changes: 3 additions & 2 deletions packages/next/src/server/lib/incremental-cache/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type {
IncrementalCacheKindHint,
} from '../../response-cache'
import type { Revalidate } from '../revalidate'
import type { DeepReadonly } from '../../../shared/lib/deep-readonly'

import FetchCache from './fetch-cache'
import FileSystemCache from './file-system-cache'
Expand Down Expand Up @@ -67,7 +68,7 @@ export class IncrementalCache implements IncrementalCacheType {
readonly disableForTestmode?: boolean
readonly cacheHandler?: CacheHandler
readonly hasCustomCacheHandler: boolean
readonly prerenderManifest: PrerenderManifest
readonly prerenderManifest: DeepReadonly<PrerenderManifest>
readonly requestHeaders: Record<string, undefined | string | string[]>
readonly requestProtocol?: 'http' | 'https'
readonly allowedRevalidateHeaderKeys?: string[]
Expand Down Expand Up @@ -115,7 +116,7 @@ export class IncrementalCache implements IncrementalCacheType {
allowedRevalidateHeaderKeys?: string[]
requestHeaders: IncrementalCache['requestHeaders']
maxMemoryCacheSize?: number
getPrerenderManifest: () => PrerenderManifest
getPrerenderManifest: () => DeepReadonly<PrerenderManifest>
fetchCacheKeyPrefix?: string
CurCacheHandler?: typeof CacheHandler
experimental: { ppr: boolean }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { PrerenderManifest } from '../../../build'
import type { DeepReadonly } from '../../../shared/lib/deep-readonly'
import type { Revalidate } from '../revalidate'

/**
Expand All @@ -18,7 +19,9 @@ export class SharedRevalidateTimings {
* The prerender manifest that contains the initial revalidate timings for
* routes.
*/
private readonly prerenderManifest: Pick<PrerenderManifest, 'routes'>
private readonly prerenderManifest: DeepReadonly<
Pick<PrerenderManifest, 'routes'>
>
) {}

/**
Expand Down
Loading