diff --git a/crates/next-api/src/app.rs b/crates/next-api/src/app.rs index 28176108990e7..c0639362a579d 100644 --- a/crates/next-api/src/app.rs +++ b/crates/next-api/src/app.rs @@ -1543,6 +1543,9 @@ impl AppEndpoint { rcstr!("server/middleware-build-manifest.js"), rcstr!("server/interception-route-rewrite-manifest.js"), ]; + if project.next_mode().await?.is_production() { + file_paths_from_root.insert(rcstr!("required-server-files.js")); + } if emit_manifests == EmitManifests::Full { file_paths_from_root.insert(rcstr!("server/next-font-manifest.js")); }; diff --git a/crates/next-api/src/pages.rs b/crates/next-api/src/pages.rs index 8a0d42340666e..7efbdef0e11f4 100644 --- a/crates/next-api/src/pages.rs +++ b/crates/next-api/src/pages.rs @@ -904,7 +904,6 @@ impl PageEndpoint { this.original_name.clone(), *this.pages_structure, runtime, - this.pages_project.project().next_config(), ) .await?; @@ -1441,6 +1440,16 @@ impl PageEndpoint { fxindexset![] }; + if this + .pages_project + .project() + .next_mode() + .await? + .is_production() + { + file_paths_from_root.insert(rcstr!("required-server-files.js")); + } + let all_assets = assets.concatenate(*referenced_assets); let assets_ref = assets.await?; diff --git a/crates/next-core/src/next_app/app_page_entry.rs b/crates/next-core/src/next_app/app_page_entry.rs index 002d280aa666d..6cb9c42c12d0f 100644 --- a/crates/next-core/src/next_app/app_page_entry.rs +++ b/crates/next-core/src/next_app/app_page_entry.rs @@ -122,7 +122,6 @@ pub async fn get_app_page_entry( project_root.clone(), rsc_entry, page, - next_config, ); }; @@ -141,21 +140,14 @@ async fn wrap_edge_page( project_root: FileSystemPath, entry: ResolvedVc>, page: AppPage, - next_config: Vc, ) -> Result>> { const INNER: &str = "INNER_PAGE_ENTRY"; - let next_config_val = &*next_config.await?; - let source = load_next_js_template( "edge-ssr-app.js", project_root.clone(), [("VAR_USERLAND", INNER), ("VAR_PAGE", &page.to_string())], - [ - // TODO do we really need to pass the entire next config here? - // This is bad for invalidation as any config change will invalidate this - ("nextConfig", &*serde_json::to_string(next_config_val)?), - ], + [], [("incrementalCacheHandler", None)], ) .await?; diff --git a/crates/next-core/src/next_app/app_route_entry.rs b/crates/next-core/src/next_app/app_route_entry.rs index 0761f3247213b..1df164f9622da 100644 --- a/crates/next-core/src/next_app/app_route_entry.rs +++ b/crates/next-core/src/next_app/app_route_entry.rs @@ -113,7 +113,6 @@ pub async fn get_app_route_entry( project_root, rsc_entry, page, - next_config, ); } @@ -132,17 +131,14 @@ async fn wrap_edge_route( project_root: FileSystemPath, entry: ResolvedVc>, page: AppPage, - next_config: Vc, ) -> Result>> { let inner = rcstr!("INNER_ROUTE_ENTRY"); - let next_config = &*next_config.await?; - let source = load_next_js_template( "edge-app-route.js", project_root.clone(), [("VAR_USERLAND", &*inner), ("VAR_PAGE", &page.to_string())], - [("nextConfig", &*serde_json::to_string(next_config)?)], + [], [], ) .await?; diff --git a/crates/next-core/src/next_pages/page_entry.rs b/crates/next-core/src/next_pages/page_entry.rs index bd167b6e3d4fc..c1ee2386ca9f7 100644 --- a/crates/next-core/src/next_pages/page_entry.rs +++ b/crates/next-core/src/next_pages/page_entry.rs @@ -16,7 +16,6 @@ use turbopack_core::{ }; use crate::{ - next_config::NextConfig, next_edge::entry::wrap_edge_entry, pages_structure::{PagesStructure, PagesStructureItem}, util::{NextRuntime, file_content_rope, load_next_js_template, pages_function_name}, @@ -39,7 +38,6 @@ pub async fn create_page_ssr_entry_module( next_original_name: RcStr, pages_structure: Vc, runtime: NextRuntime, - next_config: Vc, ) -> Result> { let definition_page = next_original_name; let definition_pathname = pathname; @@ -99,11 +97,7 @@ pub async fn create_page_ssr_entry_module( let pages_structure_ref = pages_structure.await?; let (injections, imports) = if is_page && runtime == NextRuntime::Edge { - let next_config_val = &*next_config.await?; let injections = vec![ - // TODO do we really need to pass the entire next config here? - // This is bad for invalidation as any config change will invalidate this - ("nextConfig", serde_json::to_string(next_config_val)?), ( "pageRouteModuleOptions", serde_json::to_string(&get_route_module_options( diff --git a/packages/next/errors.json b/packages/next/errors.json index 881b655830c81..493d95d7d4423 100644 --- a/packages/next/errors.json +++ b/packages/next/errors.json @@ -965,5 +965,7 @@ "964": "An unexpected error occurred while starting to capture immediates", "965": "Expected setImmediate to reject invalid arguments", "966": "Expected process.nextTick to reject invalid arguments", - "967": "The key \"%s\" under \"env\" in %sconfig is not allowed. https://nextjs.org/docs/messages/env-key-not-allowed" + "967": "The key \"%s\" under \"env\" in %sconfig is not allowed. https://nextjs.org/docs/messages/env-key-not-allowed", + "968": "Invariant: getNextConfigEdge must only be called in edge runtime", + "969": "Invariant: nextConfig couldn't be loaded" } diff --git a/packages/next/src/build/define-env.ts b/packages/next/src/build/define-env.ts index 3cb419e5bb264..1c60e0b006a7d 100644 --- a/packages/next/src/build/define-env.ts +++ b/packages/next/src/build/define-env.ts @@ -296,7 +296,7 @@ export function getDefineEnv({ config.experimental.trustHostHeader ?? false, 'process.env.__NEXT_ALLOWED_REVALIDATE_HEADERS': config.experimental.allowedRevalidateHeaderKeys ?? [], - ...(isNodeServer + ...(isNodeServer || isEdgeServer ? { 'process.env.__NEXT_RELATIVE_DIST_DIR': config.distDir, 'process.env.__NEXT_RELATIVE_PROJECT_DIR': path.relative( diff --git a/packages/next/src/build/entries.ts b/packages/next/src/build/entries.ts index 5235b85b7dbbc..25258e16bd7ab 100644 --- a/packages/next/src/build/entries.ts +++ b/packages/next/src/build/entries.ts @@ -621,7 +621,6 @@ export function getEdgeServerEntry(opts: { absolutePagePath: opts.absolutePagePath, page: opts.page, appDirLoader: Buffer.from(opts.appDirLoader || '').toString('base64'), - nextConfig: Buffer.from(JSON.stringify(opts.config)).toString('base64'), preferredRegion: opts.preferredRegion, middlewareConfig: Buffer.from( JSON.stringify(opts.middlewareConfig || {}) @@ -682,9 +681,6 @@ export function getEdgeServerEntry(opts: { dev: opts.isDev, isServerComponent: opts.isServerComponent, page: opts.page, - stringifiedConfig: Buffer.from(JSON.stringify(opts.config)).toString( - 'base64' - ), pagesType: opts.pagesType, appDirLoader: Buffer.from(opts.appDirLoader || '').toString('base64'), sriEnabled: !opts.isDev && !!opts.config.experimental.sri?.algorithm, diff --git a/packages/next/src/build/index.ts b/packages/next/src/build/index.ts index be9d2b1b7c806..fe5ce8848dd53 100644 --- a/packages/next/src/build/index.ts +++ b/packages/next/src/build/index.ts @@ -621,9 +621,13 @@ async function writeRequiredServerFilesManifest( requiredServerFiles: RequiredServerFilesManifest ) { await writeManifest( - path.join(distDir, SERVER_FILES_MANIFEST), + path.join(distDir, SERVER_FILES_MANIFEST + '.json'), requiredServerFiles ) + await writeFileUtf8( + path.join(distDir, SERVER_FILES_MANIFEST + '.js'), + `self.__SERVER_FILES_MANIFEST=${formatManifest(requiredServerFiles)}` + ) } async function writeImagesManifest( @@ -693,7 +697,10 @@ async function writeStandaloneDirectory( for (const file of [ ...requiredServerFiles.files, - path.join(requiredServerFiles.config.distDir, SERVER_FILES_MANIFEST), + path.join( + requiredServerFiles.config.distDir, + SERVER_FILES_MANIFEST + '.json' + ), ...loadedEnvFiles.reduce((acc, envFile) => { if (['.env', '.env.production'].includes(envFile.path)) { acc.push(envFile.path) @@ -1915,7 +1922,7 @@ export default async function build( BUILD_ID_FILE, path.join(SERVER_DIRECTORY, NEXT_FONT_MANIFEST + '.js'), path.join(SERVER_DIRECTORY, NEXT_FONT_MANIFEST + '.json'), - SERVER_FILES_MANIFEST, + SERVER_FILES_MANIFEST + '.json', ] .filter(nonNullable) .map((file) => path.join(config.distDir, file)), diff --git a/packages/next/src/build/templates/edge-app-route.ts b/packages/next/src/build/templates/edge-app-route.ts index d9d75d21a571b..439ae20cbd5a6 100644 --- a/packages/next/src/build/templates/edge-app-route.ts +++ b/packages/next/src/build/templates/edge-app-route.ts @@ -1,5 +1,4 @@ import { setManifestsSingleton } from '../../server/app-render/manifests-singleton' -import type { NextConfigRuntime } from '../../server/config-shared' import type { EdgeHandler } from '../../server/web/adapter' import { EdgeRouteModuleWrapper } from '../../server/web/edge-route-module-wrapper' @@ -7,8 +6,6 @@ import { EdgeRouteModuleWrapper } from '../../server/web/edge-route-module-wrapp import * as module from 'VAR_USERLAND' // injected by the loader afterwards. -declare const nextConfig: NextConfigRuntime -// INJECT:nextConfig const maybeJSONParse = (str?: string) => (str ? JSON.parse(str) : undefined) @@ -26,7 +23,6 @@ if (rscManifest && rscServerManifest) { export const ComponentMod = module const handler: EdgeHandler = EdgeRouteModuleWrapper.wrap(module.routeModule, { - nextConfig, page: 'VAR_PAGE', }) export default handler diff --git a/packages/next/src/build/templates/edge-ssr-app.ts b/packages/next/src/build/templates/edge-ssr-app.ts index c084441edf283..b694a72f4eee0 100644 --- a/packages/next/src/build/templates/edge-ssr-app.ts +++ b/packages/next/src/build/templates/edge-ssr-app.ts @@ -8,7 +8,6 @@ import { IncrementalCache } from '../../server/lib/incremental-cache' import * as pageMod from 'VAR_USERLAND' -import type { NextConfigRuntime } from '../../server/config-shared' import { setManifestsSingleton } from '../../server/app-render/manifests-singleton' import { initializeCacheHandlers } from '../../server/use-cache/handlers' import { BaseServerSpan } from '../../server/lib/trace/constants' @@ -29,12 +28,7 @@ import { checkIsOnDemandRevalidate } from '../../server/api-utils' import { CloseController } from '../../server/web/web-on-close' declare const incrementalCacheHandler: any -declare const nextConfig: NextConfigRuntime // OPTIONAL_IMPORT:incrementalCacheHandler -// INJECT:nextConfig - -// Initialize the cache handlers interface. -initializeCacheHandlers(nextConfig.cacheMaxMemorySize) const maybeJSONParse = (str?: string) => (str ? JSON.parse(str) : undefined) @@ -77,6 +71,7 @@ async function requestHandler( query, params, buildId, + nextConfig, buildManifest, prerenderManifest, reactLoadableManifest, @@ -88,6 +83,9 @@ async function requestHandler( routerServerContext, } = prepareResult + // Initialize the cache handlers interface. + initializeCacheHandlers(nextConfig.cacheMaxMemorySize) + const isPossibleServerAction = getIsPossibleServerAction(req) const botType = getBotType(req.headers.get('User-Agent') || '') const { isOnDemandRevalidate } = checkIsOnDemandRevalidate( diff --git a/packages/next/src/build/templates/edge-ssr.ts b/packages/next/src/build/templates/edge-ssr.ts index b68a87cadeafa..ca4f2040e3712 100644 --- a/packages/next/src/build/templates/edge-ssr.ts +++ b/packages/next/src/build/templates/edge-ssr.ts @@ -22,7 +22,6 @@ import RouteModule, { } from '../../server/route-modules/pages/module' import { WebNextRequest, WebNextResponse } from '../../server/base-http/web' -import type { NextConfigRuntime } from '../../server/config-shared' import type { NextFetchEvent } from '../../server/web/spec-extension/fetch-event' import type RenderResult from '../../server/render-result' import type { RenderResultMetadata } from '../../server/render-result' @@ -31,21 +30,13 @@ import { BaseServerSpan } from '../../server/lib/trace/constants' import { HTML_CONTENT_TYPE_HEADER } from '../../lib/constants' // injected by the loader afterwards. -declare const nextConfig: NextConfigRuntime declare const pageRouteModuleOptions: any declare const errorRouteModuleOptions: any declare const user500RouteModuleOptions: any -// INJECT:nextConfig // INJECT:pageRouteModuleOptions // INJECT:errorRouteModuleOptions // INJECT:user500RouteModuleOptions -// Initialize the cache handlers interface. -initializeCacheHandlers(nextConfig.cacheMaxMemorySize) - -// expose this for the route-module -;(globalThis as any).nextConfig = nextConfig - const pageMod = { ...userlandPage, routeModule: new RouteModule({ @@ -55,6 +46,8 @@ const pageMod = { Document, }, userland: userlandPage, + distDir: process.env.__NEXT_RELATIVE_DIST_DIR || '', + relativeProjectDir: process.env.__NEXT_RELATIVE_PROJECT_DIR || '', }), } @@ -67,6 +60,8 @@ const errorMod = { Document, }, userland: userlandErrorPage, + distDir: process.env.__NEXT_RELATIVE_DIST_DIR || '', + relativeProjectDir: process.env.__NEXT_RELATIVE_PROJECT_DIR || '', }), } @@ -81,6 +76,8 @@ const error500Mod = userland500Page Document, }, userland: userland500Page, + distDir: process.env.__NEXT_RELATIVE_DIST_DIR || '', + relativeProjectDir: process.env.__NEXT_RELATIVE_PROJECT_DIR || '', }), } : null @@ -110,6 +107,7 @@ async function requestHandler( query, params, buildId, + nextConfig, isNextDataRequest, buildManifest, prerenderManifest, @@ -119,6 +117,8 @@ async function requestHandler( dynamicCssManifest, } = prepareResult + initializeCacheHandlers(nextConfig.cacheMaxMemorySize) + const renderContext: PagesRouteHandlerContext = { page: srcPage, query, diff --git a/packages/next/src/build/webpack/loaders/next-edge-app-route-loader/index.ts b/packages/next/src/build/webpack/loaders/next-edge-app-route-loader/index.ts index aac70f5c8519b..4c692766378d4 100644 --- a/packages/next/src/build/webpack/loaders/next-edge-app-route-loader/index.ts +++ b/packages/next/src/build/webpack/loaders/next-edge-app-route-loader/index.ts @@ -11,7 +11,6 @@ export type EdgeAppRouteLoaderQuery = { page: string appDirLoader: string preferredRegion: string | string[] | undefined - nextConfig: string middlewareConfig: string cacheHandlers: string } @@ -24,7 +23,6 @@ const EdgeAppRouteLoader: webpack.LoaderDefinitionFunction = { + const options: Omit< + PagesRouteModuleOptions, + 'userland' | 'components' | 'distDir' | 'relativeProjectDir' + > = { definition: { kind: RouteKind.PAGES, page: normalizePagePath(page), @@ -55,9 +57,6 @@ function getRouteModuleOptions(page: string) { bundlePath: '', filename: '', }, - // edge runtime doesn't read from distDir or projectDir - distDir: '', - relativeProjectDir: '', } return options @@ -73,7 +72,6 @@ const edgeSSRLoader: webpack.LoaderDefinitionFunction = absolute500Path, absoluteErrorPath, isServerComponent, - stringifiedConfig: stringifiedConfigBase64, appDirLoader: appDirLoaderBase64, pagesType, cacheHandler, @@ -94,10 +92,6 @@ const edgeSSRLoader: webpack.LoaderDefinitionFunction = Buffer.from(middlewareConfigBase64, 'base64').toString() ) - const stringifiedConfig = Buffer.from( - stringifiedConfigBase64 || '', - 'base64' - ).toString() const appDirLoader = Buffer.from( appDirLoaderBase64 || '', 'base64' @@ -160,9 +154,7 @@ const edgeSSRLoader: webpack.LoaderDefinitionFunction = VAR_USERLAND: pageModPath, VAR_PAGE: page, }, - { - nextConfig: stringifiedConfig, - }, + {}, { incrementalCacheHandler: cacheHandler ?? null, } @@ -178,7 +170,6 @@ const edgeSSRLoader: webpack.LoaderDefinitionFunction = VAR_MODULE_GLOBAL_ERROR: errorPath, }, { - nextConfig: stringifiedConfig, pageRouteModuleOptions: JSON.stringify(getRouteModuleOptions(page)), errorRouteModuleOptions: JSON.stringify( getRouteModuleOptions('/_error') diff --git a/packages/next/src/build/webpack/plugins/middleware-plugin.ts b/packages/next/src/build/webpack/plugins/middleware-plugin.ts index bb347a34c9e69..43425a5c6ae37 100644 --- a/packages/next/src/build/webpack/plugins/middleware-plugin.ts +++ b/packages/next/src/build/webpack/plugins/middleware-plugin.ts @@ -22,6 +22,7 @@ import { SERVER_REFERENCE_MANIFEST, INTERCEPTION_ROUTE_REWRITE_MANIFEST, DYNAMIC_CSS_MANIFEST, + SERVER_FILES_MANIFEST, } from '../../../shared/lib/constants' import type { ProxyConfig } from '../../analysis/get-page-static-info' import type { Telemetry } from '../../../telemetry/storage' @@ -133,6 +134,10 @@ function getEntryFiles( `server/${NEXT_FONT_MANIFEST}.js`, `server/${INTERCEPTION_ROUTE_REWRITE_MANIFEST}.js` ) + + if (!opts.dev) { + files.push(`${SERVER_FILES_MANIFEST}.js`) + } } if (hasInstrumentationHook) { diff --git a/packages/next/src/client/route-loader.ts b/packages/next/src/client/route-loader.ts index 43cbda00636d1..39ce7694cfc16 100644 --- a/packages/next/src/client/route-loader.ts +++ b/packages/next/src/client/route-loader.ts @@ -1,5 +1,6 @@ import type { ComponentType } from 'react' import type { ProxyMatcher } from '../build/analysis/get-page-static-info' +import type { RequiredServerFilesManifest } from '../build' import getAssetPathFromRoute from '../shared/lib/router/utils/get-asset-path-from-route' import { __unsafeCreateTrustedScriptURL } from './trusted-types' import { requestIdleCallback } from './request-idle-callback' @@ -16,6 +17,7 @@ declare global { interface Window { __BUILD_MANIFEST?: Record __BUILD_MANIFEST_CB?: Function + __SERVER_FILES_MANIFEST?: RequiredServerFilesManifest __MIDDLEWARE_MATCHERS?: ProxyMatcher[] __MIDDLEWARE_MANIFEST_CB?: Function __REACT_LOADABLE_MANIFEST?: any diff --git a/packages/next/src/server/next.ts b/packages/next/src/server/next.ts index f2cb853b212fd..e2274aaa8eaaf 100644 --- a/packages/next/src/server/next.ts +++ b/packages/next/src/server/next.ts @@ -298,7 +298,7 @@ export class NextServer implements NextWrapperServer { path.join( /* turbopackIgnore: true */ dir, config.distDir, - SERVER_FILES_MANIFEST + SERVER_FILES_MANIFEST + '.json' ) ).config diff --git a/packages/next/src/server/route-modules/route-module.ts b/packages/next/src/server/route-modules/route-module.ts index 5ee7590ab0baf..25617a653c80e 100644 --- a/packages/next/src/server/route-modules/route-module.ts +++ b/packages/next/src/server/route-modules/route-module.ts @@ -42,7 +42,11 @@ import type { ReactLoadableManifest } from '../load-components' import type { NextFontManifest } from '../../build/webpack/plugins/next-font-manifest-plugin' import { normalizeDataPath } from '../../shared/lib/page-path/normalize-data-path' import { pathHasPrefix } from '../../shared/lib/router/utils/path-has-prefix' -import { addRequestMeta, getRequestMeta } from '../request-meta' +import { + addRequestMeta, + getRequestMeta, + type NextIncomingMessage, +} from '../request-meta' import { normalizePagePath } from '../../shared/lib/page-path/normalize-page-path' import { isStaticMetadataRoute } from '../../lib/metadata/is-metadata-route' import { IncrementalCache } from '../lib/incremental-cache' @@ -178,7 +182,7 @@ export abstract class RouteModule< routesManifest: DeepReadonly nextFontManifest: DeepReadonly prerenderManifest: DeepReadonly - serverFilesManifest: RequiredServerFilesManifest + serverFilesManifest: RequiredServerFilesManifest | undefined reactLoadableManifest: DeepReadonly subresourceIntegrityManifest: any clientReferenceManifest: any @@ -223,9 +227,7 @@ export abstract class RouteModule< process.env.__NEXT_NO_MIDDLEWARE_URL_NORMALIZE ), }, - serverFilesManifest: { - config: (globalThis as any).nextConfig || {}, - } as any, + serverFilesManifest: self.__SERVER_FILES_MANIFEST, clientReferenceManifest: self.__RSC_MANIFEST?.[srcPage], serverActionsManifest: maybeJSONParse(self.__RSC_SERVER_MANIFEST), subresourceIntegrityManifest: maybeJSONParse( @@ -333,12 +335,12 @@ export abstract class RouteModule< shouldCache: !this.isDev, }), this.isDev - ? ({} as any) - : loadManifestFromRelativePath({ + ? undefined + : (loadManifestFromRelativePath({ projectDir, distDir: this.distDir, - manifest: SERVER_FILES_MANIFEST, - }), + manifest: `${SERVER_FILES_MANIFEST}.json`, + }) as RequiredServerFilesManifest), this.isDev ? 'development' : loadManifestFromRelativePath({ @@ -500,6 +502,31 @@ export abstract class RouteModule< ) } + /** A more lightweight version of `prepare()` for only retrieving the config on edge */ + public getNextConfigEdge(req: NextIncomingMessage): NextConfigRuntime { + if (process.env.NEXT_RUNTIME !== 'edge') { + throw new Error( + 'Invariant: getNextConfigEdge must only be called in edge runtime' + ) + } + + let serverFilesManifest = self.__SERVER_FILES_MANIFEST as any as + | RequiredServerFilesManifest + | undefined + const relativeProjectDir = + getRequestMeta(req, 'relativeProjectDir') || this.relativeProjectDir + const routerServerContext = + routerServerGlobal[RouterServerContextSymbol]?.[relativeProjectDir] + const nextConfig = + routerServerContext?.nextConfig || serverFilesManifest?.config + + if (!nextConfig) { + throw new Error("Invariant: nextConfig couldn't be loaded") + } + + return nextConfig + } + public async prepare( req: IncomingMessage | BaseNextRequest, res: ServerResponse | null, @@ -530,7 +557,9 @@ export abstract class RouteModule< buildManifest: DeepReadonly fallbackBuildManifest: DeepReadonly nextFontManifest: DeepReadonly - serverFilesManifest: DeepReadonly + serverFilesManifest: + | DeepReadonly + | undefined reactLoadableManifest: DeepReadonly routesManifest: DeepReadonly prerenderManifest: DeepReadonly @@ -849,7 +878,11 @@ export abstract class RouteModule< const routerServerContext = routerServerGlobal[RouterServerContextSymbol]?.[relativeProjectDir] const nextConfig = - routerServerContext?.nextConfig || serverFilesManifest.config + routerServerContext?.nextConfig || serverFilesManifest?.config + + if (!nextConfig) { + throw new Error("Invariant: nextConfig couldn't be loaded") + } let resolvedPathname = normalizedSrcPage if (isDynamicRoute(resolvedPathname) && params) { @@ -890,7 +923,6 @@ export abstract class RouteModule< isOnDemandRevalidate, revalidateOnlyGenerated, ...manifests, - serverActionsManifest: manifests.serverActionsManifest, clientReferenceManifest: manifests.clientReferenceManifest, nextConfig, routerServerContext, diff --git a/packages/next/src/server/web/edge-route-module-wrapper.ts b/packages/next/src/server/web/edge-route-module-wrapper.ts index b9f598c9a24d3..f53b6bb3de32f 100644 --- a/packages/next/src/server/web/edge-route-module-wrapper.ts +++ b/packages/next/src/server/web/edge-route-module-wrapper.ts @@ -1,4 +1,3 @@ -import type { NextRequest } from './spec-extension/request' import type { AppRouteRouteHandlerContext, AppRouteRouteModule, @@ -6,7 +5,7 @@ import type { import './globals' -import { adapter, type EdgeHandler } from './adapter' +import { adapter, type NextRequestHint, type EdgeHandler } from './adapter' import { IncrementalCache } from '../lib/incremental-cache' import { RouteMatcher } from '../route-matchers/route-matcher' import type { NextFetchEvent } from './spec-extension/fetch-event' @@ -15,10 +14,9 @@ import { getServerUtils } from '../server-utils' import { searchParamsToUrlQuery } from '../../shared/lib/router/utils/querystring' import { CloseController, trackStreamConsumed } from './web-on-close' import { getEdgePreviewProps } from './get-edge-preview-props' -import type { NextConfigRuntime } from '../config-shared' +import { WebNextRequest } from '../../server/base-http/web' export interface WrapOptions { - nextConfig: NextConfigRuntime page: string } @@ -36,10 +34,7 @@ export class EdgeRouteModuleWrapper { * * @param routeModule the route module to wrap */ - private constructor( - private readonly routeModule: AppRouteRouteModule, - private readonly nextConfig: NextConfigRuntime - ) { + private constructor(private readonly routeModule: AppRouteRouteModule) { // TODO: (wyattjoh) possibly allow the module to define it's own matcher this.matcher = new RouteMatcher(routeModule.definition) } @@ -58,7 +53,7 @@ export class EdgeRouteModuleWrapper { options: WrapOptions ): EdgeHandler { // Create the module wrapper. - const wrapper = new EdgeRouteModuleWrapper(routeModule, options.nextConfig) + const wrapper = new EdgeRouteModuleWrapper(routeModule) // Return the wrapping function. return (opts) => { @@ -73,7 +68,7 @@ export class EdgeRouteModuleWrapper { } private async handler( - request: NextRequest, + request: NextRequestHint, evt: NextFetchEvent ): Promise { const utils = getServerUtils({ @@ -86,6 +81,10 @@ export class EdgeRouteModuleWrapper { caseSensitive: false, }) + const nextConfig = this.routeModule.getNextConfigEdge( + new WebNextRequest(request) + ) + const { params } = utils.normalizeDynamicRouteParams( searchParamsToUrlQuery(request.nextUrl.searchParams), false @@ -116,7 +115,7 @@ export class EdgeRouteModuleWrapper { experimental: { authInterrupts: !!process.env.__NEXT_EXPERIMENTAL_AUTH_INTERRUPTS, }, - cacheLifeProfiles: this.nextConfig.cacheLife, + cacheLifeProfiles: nextConfig.cacheLife, }, sharedContext: { buildId: '', // TODO: Populate this properly. diff --git a/packages/next/src/server/web/sandbox/context.ts b/packages/next/src/server/web/sandbox/context.ts index 3905f873bbfb3..431505ae5165b 100644 --- a/packages/next/src/server/web/sandbox/context.ts +++ b/packages/next/src/server/web/sandbox/context.ts @@ -118,12 +118,11 @@ async function loadWasm( function buildEnvironmentVariablesFrom( injectedEnvironments: Record ): Record { - const pairs = Object.keys(process.env).map((key) => [key, process.env[key]]) - const env = Object.fromEntries(pairs) - for (const key of Object.keys(injectedEnvironments)) { - env[key] = injectedEnvironments[key] - } - env.NEXT_RUNTIME = 'edge' + let env = Object.fromEntries([ + ...Object.entries(process.env), + ...Object.entries(injectedEnvironments), + ['NEXT_RUNTIME', 'edge'], + ]) return env } diff --git a/packages/next/src/shared/lib/constants.ts b/packages/next/src/shared/lib/constants.ts index b6c2d7771fddc..6840785b65122 100644 --- a/packages/next/src/shared/lib/constants.ts +++ b/packages/next/src/shared/lib/constants.ts @@ -97,7 +97,7 @@ export const EXPORT_DETAIL = 'export-detail.json' export const PRERENDER_MANIFEST = 'prerender-manifest.json' export const ROUTES_MANIFEST = 'routes-manifest.json' export const IMAGES_MANIFEST = 'images-manifest.json' -export const SERVER_FILES_MANIFEST = 'required-server-files.json' +export const SERVER_FILES_MANIFEST = 'required-server-files' export const DEV_CLIENT_PAGES_MANIFEST = '_devPagesManifest.json' export const MIDDLEWARE_MANIFEST = 'middleware-manifest.json' export const TURBOPACK_CLIENT_MIDDLEWARE_MANIFEST =