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

Add SRI support for Node.js Runtime #73891

Merged
merged 5 commits into from
Dec 17, 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
6 changes: 6 additions & 0 deletions packages/next/src/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1864,6 +1864,7 @@ export default async function build(
const { configFileName, publicRuntimeConfig, serverRuntimeConfig } =
config
const runtimeEnvConfig = { publicRuntimeConfig, serverRuntimeConfig }
const sriEnabled = Boolean(config.experimental.sri?.algorithm)

const nonStaticErrorPageSpan = staticCheckSpan.traceChild(
'check-static-error-page'
Expand All @@ -1877,6 +1878,7 @@ export default async function build(
distDir,
runtimeEnvConfig,
checkingApp: false,
sriEnabled,
}))
)

Expand All @@ -1898,6 +1900,7 @@ export default async function build(
pprConfig: config.experimental.ppr,
cacheLifeProfiles: config.experimental.cacheLife,
buildId,
sriEnabled,
})
)

Expand All @@ -1909,13 +1912,15 @@ export default async function build(
distDir,
runtimeEnvConfig,
checkingApp: true,
sriEnabled,
}
)

const namedExportsPromise = worker.getDefinedNamedExports({
page: appPageToCheck,
distDir,
runtimeEnvConfig,
sriEnabled,
})

// eslint-disable-next-line @typescript-eslint/no-shadow
Expand Down Expand Up @@ -2125,6 +2130,7 @@ export default async function build(
pprConfig: config.experimental.ppr,
cacheLifeProfiles: config.experimental.cacheLife,
buildId,
sriEnabled,
})
}
)
Expand Down
9 changes: 9 additions & 0 deletions packages/next/src/build/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -972,6 +972,7 @@ export async function isPageStatic({
cacheLifeProfiles,
pprConfig,
buildId,
sriEnabled,
}: {
dir: string
page: string
Expand All @@ -998,6 +999,7 @@ export async function isPageStatic({
nextConfigOutput: 'standalone' | 'export' | undefined
pprConfig: ExperimentalPPRConfig | undefined
buildId: string
sriEnabled: boolean
}): Promise<PageIsStaticResult> {
await createIncrementalCache({
cacheHandler,
Expand Down Expand Up @@ -1069,6 +1071,7 @@ export async function isPageStatic({
page: originalAppPath || page,
isAppPath: pageType === 'app',
isDev: false,
sriEnabled,
})
}
const Comp = componentsResult.Component as NextComponentType | undefined
Expand Down Expand Up @@ -1316,11 +1319,13 @@ export async function hasCustomGetInitialProps({
distDir,
runtimeEnvConfig,
checkingApp,
sriEnabled,
}: {
page: string
distDir: string
runtimeEnvConfig: any
checkingApp: boolean
sriEnabled: boolean
}): Promise<boolean> {
require('../shared/lib/runtime-config.external').setConfig(runtimeEnvConfig)

Expand All @@ -1329,6 +1334,7 @@ export async function hasCustomGetInitialProps({
page: page,
isAppPath: false,
isDev: false,
sriEnabled,
})
let mod = components.ComponentMod

Expand All @@ -1345,17 +1351,20 @@ export async function getDefinedNamedExports({
page,
distDir,
runtimeEnvConfig,
sriEnabled,
}: {
page: string
distDir: string
runtimeEnvConfig: any
sriEnabled: boolean
}): Promise<ReadonlyArray<string>> {
require('../shared/lib/runtime-config.external').setConfig(runtimeEnvConfig)
const components = await loadComponents({
distDir,
page: page,
isAppPath: false,
isDev: false,
sriEnabled,
})

return Object.keys(components.ComponentMod).filter((key) => {
Expand Down
1 change: 1 addition & 0 deletions packages/next/src/export/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export interface ExportPageInput {
debugOutput?: boolean
nextConfigOutput?: NextConfigComplete['output']
enableExperimentalReact?: boolean
sriEnabled: boolean
}

export type ExportedPageFile = {
Expand Down
3 changes: 3 additions & 0 deletions packages/next/src/export/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ async function exportPageImpl(
enableExperimentalReact,
ampValidatorPath,
trailingSlash,
sriEnabled,
} = input

if (enableExperimentalReact) {
Expand Down Expand Up @@ -234,6 +235,7 @@ async function exportPageImpl(
page,
isAppPath: isAppDir,
isDev: false,
sriEnabled,
})

// Handle App Routes.
Expand Down Expand Up @@ -396,6 +398,7 @@ export async function exportPages(
httpAgentOptions: nextConfig.httpAgentOptions,
debugOutput: options.debugOutput,
enableExperimentalReact: needsExperimentalReact(nextConfig),
sriEnabled: Boolean(nextConfig.experimental.sri?.algorithm),
}),
// If exporting the page takes longer than the timeout, reject the promise.
new Promise((_, reject) => {
Expand Down
3 changes: 2 additions & 1 deletion packages/next/src/server/dev/next-dev-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,8 @@ export default class DevServer extends Server {
maxMemoryCacheSize: this.nextConfig.cacheMaxMemorySize,
nextConfigOutput: this.nextConfig.output,
buildId: this.renderOpts.buildId,
authInterrupts: !!this.nextConfig.experimental.authInterrupts,
authInterrupts: Boolean(this.nextConfig.experimental.authInterrupts),
sriEnabled: Boolean(this.nextConfig.experimental.sri?.algorithm),
})
return pathsResult
} finally {
Expand Down
3 changes: 3 additions & 0 deletions packages/next/src/server/dev/static-paths-worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export async function loadStaticPaths({
nextConfigOutput,
buildId,
authInterrupts,
sriEnabled,
}: {
dir: string
distDir: string
Expand All @@ -70,6 +71,7 @@ export async function loadStaticPaths({
nextConfigOutput: 'standalone' | 'export' | undefined
buildId: string
authInterrupts: boolean
sriEnabled: boolean
}): Promise<Partial<StaticPathsResult>> {
// update work memory runtime-config
require('../../shared/lib/runtime-config.external').setConfig(config)
Expand All @@ -83,6 +85,7 @@ export async function loadStaticPaths({
page: page || pathname,
isAppPath,
isDev: true,
sriEnabled,
})

if (isAppPath) {
Expand Down
10 changes: 10 additions & 0 deletions packages/next/src/server/load-components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
CLIENT_REFERENCE_MANIFEST,
SERVER_REFERENCE_MANIFEST,
DYNAMIC_CSS_MANIFEST,
SUBRESOURCE_INTEGRITY_MANIFEST,
} from '../shared/lib/constants'
import { join } from 'path'
import { requirePage } from './require'
Expand Down Expand Up @@ -136,11 +137,13 @@ async function loadComponentsImpl<N = any>({
page,
isAppPath,
isDev,
sriEnabled,
}: {
distDir: string
page: string
isAppPath: boolean
isDev: boolean
sriEnabled: boolean
}): Promise<LoadComponentsReturnType<N>> {
let DocumentMod = {}
let AppMod = {}
Expand All @@ -167,6 +170,7 @@ async function loadComponentsImpl<N = any>({
dynamicCssManifest,
clientReferenceManifest,
serverActionsManifest,
subresourceIntegrityManifest,
] = await Promise.all([
loadManifestWithRetries<BuildManifest>(
join(distDir, BUILD_MANIFEST),
Expand Down Expand Up @@ -201,6 +205,11 @@ async function loadComponentsImpl<N = any>({
manifestLoadAttempts
).catch(() => null)
: null,
sriEnabled
? loadManifestWithRetries<DeepReadonly<Record<string, string>>>(
join(distDir, 'server', SUBRESOURCE_INTEGRITY_MANIFEST + '.json')
).catch(() => undefined)
: undefined,
])

// Before requiring the actual page module, we have to set the reference
Expand Down Expand Up @@ -231,6 +240,7 @@ async function loadComponentsImpl<N = any>({
Document,
Component,
buildManifest,
subresourceIntegrityManifest,
reactLoadableManifest,
dynamicCssManifest,
pageConfig: ComponentMod.config || {},
Expand Down
7 changes: 7 additions & 0 deletions packages/next/src/server/next-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,12 +179,14 @@ export default class NextNodeServer extends BaseServer<
protected cleanupListeners = new AsyncCallbackSet()
protected internalWaitUntil: WaitUntil | undefined
private isDev: boolean
private sriEnabled: boolean

constructor(options: Options) {
// Initialize super class
super(options)

this.isDev = options.dev ?? false
this.sriEnabled = Boolean(options.conf.experimental?.sri?.algorithm)

/**
* This sets environment variable to be used at the time of SSR by head.tsx.
Expand Down Expand Up @@ -218,12 +220,14 @@ export default class NextNodeServer extends BaseServer<
page: '/_document',
isAppPath: false,
isDev: this.isDev,
sriEnabled: this.sriEnabled,
}).catch(() => {})
loadComponents({
distDir: this.distDir,
page: '/_app',
isAppPath: false,
isDev: this.isDev,
sriEnabled: this.sriEnabled,
}).catch(() => {})
}

Expand Down Expand Up @@ -285,6 +289,7 @@ export default class NextNodeServer extends BaseServer<
page,
isAppPath: false,
isDev: this.isDev,
sriEnabled: this.sriEnabled,
}).catch(() => {})
}

Expand All @@ -294,6 +299,7 @@ export default class NextNodeServer extends BaseServer<
page,
isAppPath: true,
isDev: this.isDev,
sriEnabled: this.sriEnabled,
})
.then(async ({ ComponentMod }) => {
// we need to ensure fetch is patched before we require the page,
Expand Down Expand Up @@ -805,6 +811,7 @@ export default class NextNodeServer extends BaseServer<
page: pagePath,
isAppPath,
isDev: this.isDev,
sriEnabled: this.sriEnabled,
})

if (
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { default } from '../node/page'

export const runtime = 'edge'
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export const dynamic = 'force-dynamic'

export default function Page() {
return <p>hello world</p>
}
Loading
Loading