From 888008dfa1f4be9d72d363fc4f307ab6336f1b0c Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Wed, 4 Oct 2023 18:32:44 -0600 Subject: [PATCH] refactor: enforce typings on component modules --- packages/next/src/build/templates/app-page.ts | 12 ++-- .../next/src/build/templates/app-route.ts | 12 ++-- .../src/build/templates/edge-app-route.ts | 1 - .../next/src/build/templates/middleware.ts | 5 +- .../next/src/build/templates/pages-api.ts | 9 +-- .../src/build/templates/pages-edge-api.ts | 5 +- packages/next/src/build/templates/pages.ts | 9 +-- packages/next/src/build/utils.ts | 27 ++------ .../build/webpack/loaders/next-app-loader.ts | 2 +- .../next/src/server/app-render/app-render.tsx | 68 +++++++------------ .../create-server-components-renderer.tsx | 9 +-- .../next/src/server/app-render/entry-base.ts | 8 +-- packages/next/src/server/app-render/types.ts | 6 +- .../app-page/module.compiled.d.ts | 1 + ...{module.compiled.ts => module.compiled.js} | 0 .../future/route-modules/app-page/module.ts | 7 ++ .../app-route/module.compiled.d.ts | 1 + ...{module.compiled.ts => module.compiled.js} | 0 .../future/route-modules/app-route/module.ts | 7 ++ .../pages-api/module.compiled.d.ts | 1 + ...{module.compiled.ts => module.compiled.js} | 0 .../future/route-modules/pages-api/module.ts | 7 ++ .../route-modules/pages/module.compiled.d.ts | 1 + ...{module.compiled.ts => module.compiled.js} | 0 .../future/route-modules/pages/module.ts | 6 ++ packages/next/src/server/lib/patch-fetch.ts | 10 +-- packages/next/src/server/load-components.ts | 8 +-- packages/next/src/server/render.tsx | 4 +- packages/next/types/compiled.d.ts | 9 +++ packages/next/types/misc.d.ts | 5 ++ packages/next/types/webpack.d.ts | 5 +- 31 files changed, 121 insertions(+), 124 deletions(-) create mode 100644 packages/next/src/server/future/route-modules/app-page/module.compiled.d.ts rename packages/next/src/server/future/route-modules/app-page/{module.compiled.ts => module.compiled.js} (100%) create mode 100644 packages/next/src/server/future/route-modules/app-route/module.compiled.d.ts rename packages/next/src/server/future/route-modules/app-route/{module.compiled.ts => module.compiled.js} (100%) create mode 100644 packages/next/src/server/future/route-modules/pages-api/module.compiled.d.ts rename packages/next/src/server/future/route-modules/pages-api/{module.compiled.ts => module.compiled.js} (100%) create mode 100644 packages/next/src/server/future/route-modules/pages/module.compiled.d.ts rename packages/next/src/server/future/route-modules/pages/{module.compiled.ts => module.compiled.js} (100%) diff --git a/packages/next/src/build/templates/app-page.ts b/packages/next/src/build/templates/app-page.ts index f0d2ab692e2a..11dba21ddded 100644 --- a/packages/next/src/build/templates/app-page.ts +++ b/packages/next/src/build/templates/app-page.ts @@ -1,13 +1,14 @@ import type { LoaderTree } from '../../server/lib/app-dir-module' -// @ts-ignore this need to be imported from next/dist to be external -import * as module from 'next/dist/server/future/route-modules/app-page/module.compiled' +import { AppPageRouteModule } from '../../server/future/route-modules/app-page/module.compiled' import { RouteKind } from '../../server/future/route-kind' -const AppPageRouteModule = - module.AppPageRouteModule as unknown as typeof import('../../server/future/route-modules/app-page/module').AppPageRouteModule - // These are injected by the loader afterwards. + +/** + * The tree created in next-app-loader that holds component segments and modules + * and I've updated it. + */ declare const tree: LoaderTree declare const pages: any @@ -18,7 +19,6 @@ declare const pages: any export { tree, pages } -// @ts-expect-error - replaced by webpack/turbopack loader export { default as GlobalError } from 'VAR_MODULE_GLOBAL_ERROR' // These are injected by the loader afterwards. diff --git a/packages/next/src/build/templates/app-route.ts b/packages/next/src/build/templates/app-route.ts index b4b8e5b0fe6c..2b8f9d101aee 100644 --- a/packages/next/src/build/templates/app-route.ts +++ b/packages/next/src/build/templates/app-route.ts @@ -1,17 +1,13 @@ import '../../server/node-polyfill-headers' -// @ts-ignore this need to be imported from next/dist to be external -import * as module from 'next/dist/server/future/route-modules/app-route/module.compiled' - -import type { AppRouteRouteModuleOptions } from '../../server/future/route-modules/app-route/module' +import { + AppRouteRouteModule, + type AppRouteRouteModuleOptions, +} from '../../server/future/route-modules/app-route/module.compiled' import { RouteKind } from '../../server/future/route-kind' -// @ts-expect-error - replaced by webpack/turbopack loader import * as userland from 'VAR_USERLAND' -const AppRouteRouteModule = - module.AppRouteRouteModule as unknown as typeof import('../../server/future/route-modules/app-route/module').AppRouteRouteModule - // These are injected by the loader afterwards. This is injected as a variable // instead of a replacement because this could also be `undefined` instead of // an empty string. diff --git a/packages/next/src/build/templates/edge-app-route.ts b/packages/next/src/build/templates/edge-app-route.ts index 69b12643ecfa..226252d06908 100644 --- a/packages/next/src/build/templates/edge-app-route.ts +++ b/packages/next/src/build/templates/edge-app-route.ts @@ -1,7 +1,6 @@ import { EdgeRouteModuleWrapper } from '../../server/web/edge-route-module-wrapper' // Import the userland code. -// @ts-expect-error - replaced by webpack/turbopack loader import * as module from 'VAR_USERLAND' export const ComponentMod = module diff --git a/packages/next/src/build/templates/middleware.ts b/packages/next/src/build/templates/middleware.ts index 15dda841e113..3ede209e4d28 100644 --- a/packages/next/src/build/templates/middleware.ts +++ b/packages/next/src/build/templates/middleware.ts @@ -1,9 +1,10 @@ -import '../../server/web/globals' import type { AdapterOptions } from '../../server/web/adapter' + +import '../../server/web/globals' + import { adapter } from '../../server/web/adapter' // Import the userland code. -// @ts-expect-error - replaced by webpack/turbopack loader import * as _mod from 'VAR_USERLAND' const mod = { ..._mod } diff --git a/packages/next/src/build/templates/pages-api.ts b/packages/next/src/build/templates/pages-api.ts index eaeec836cb61..54033fe42908 100644 --- a/packages/next/src/build/templates/pages-api.ts +++ b/packages/next/src/build/templates/pages-api.ts @@ -1,14 +1,9 @@ -// @ts-ignore this need to be imported from next/dist to be external -import * as module from 'next/dist/server/future/route-modules/pages-api/module.compiled' - +import { PagesAPIRouteModule } from '../../server/future/route-modules/pages-api/module.compiled' import { RouteKind } from '../../server/future/route-kind' -import { hoist } from './helpers' -const PagesAPIRouteModule = - module.PagesAPIRouteModule as unknown as typeof import('../../server/future/route-modules/pages-api/module').PagesAPIRouteModule +import { hoist } from './helpers' // Import the userland code. -// @ts-expect-error - replaced by webpack/turbopack loader import * as userland from 'VAR_USERLAND' // Re-export the handler (should be the default export). diff --git a/packages/next/src/build/templates/pages-edge-api.ts b/packages/next/src/build/templates/pages-edge-api.ts index 7d453a69720b..90b31feb21aa 100644 --- a/packages/next/src/build/templates/pages-edge-api.ts +++ b/packages/next/src/build/templates/pages-edge-api.ts @@ -1,10 +1,11 @@ -import '../../server/web/globals' import type { AdapterOptions } from '../../server/web/adapter' + +import '../../server/web/globals' + import { adapter } from '../../server/web/adapter' import { IncrementalCache } from '../../server/lib/incremental-cache' // Import the userland code. -// @ts-expect-error - replaced by webpack/turbopack loader import handler from 'VAR_USERLAND' const page = 'VAR_DEFINITION_PAGE' diff --git a/packages/next/src/build/templates/pages.ts b/packages/next/src/build/templates/pages.ts index b5def5d13c55..87093f682e65 100644 --- a/packages/next/src/build/templates/pages.ts +++ b/packages/next/src/build/templates/pages.ts @@ -1,21 +1,14 @@ -// @ts-ignore this need to be imported from next/dist to be external -import * as module from 'next/dist/server/future/route-modules/pages/module.compiled' +import { PagesRouteModule } from '../../server/future/route-modules/pages/module.compiled' import { RouteKind } from '../../server/future/route-kind' import { hoist } from './helpers' // Import the app and document modules. -// @ts-expect-error - replaced by webpack/turbopack loader import Document from 'VAR_MODULE_DOCUMENT' -// @ts-expect-error - replaced by webpack/turbopack loader import App from 'VAR_MODULE_APP' // Import the userland code. -// @ts-expect-error - replaced by webpack/turbopack loader import * as userland from 'VAR_USERLAND' -const PagesRouteModule = - module.PagesRouteModule as unknown as typeof import('../../server/future/route-modules/pages/module').PagesRouteModule - // Re-export the component (should be the default export). export default hoist(userland, 'default') diff --git a/packages/next/src/build/utils.ts b/packages/next/src/build/utils.ts index b12532aad7b1..824d86b9845e 100644 --- a/packages/next/src/build/utils.ts +++ b/packages/next/src/build/utils.ts @@ -14,8 +14,8 @@ import type { EdgeFunctionDefinition, MiddlewareManifest, } from './webpack/plugins/middleware-plugin' -import type { StaticGenerationAsyncStorage } from '../client/components/static-generation-async-storage.external' import type { WebpackLayerName } from '../lib/constants' +import type { AppPageModule } from '../server/future/route-modules/app-page/module' import '../server/require-hook' import '../server/node-polyfill-fetch' @@ -68,9 +68,7 @@ import { nodeFs } from '../server/lib/node-fs-methods' import * as ciEnvironment from '../telemetry/ci-info' import { normalizeAppPath } from '../shared/lib/router/utils/app-paths' import { denormalizeAppPagePath } from '../shared/lib/page-path/denormalize-app-path' - -const { AppRouteRouteModule } = - require('../server/future/route-modules/app-route/module.compiled') as typeof import('../server/future/route-modules/app-route/module') +import { AppRouteRouteModule } from '../server/future/route-modules/app-route/module.compiled' export type ROUTER_TYPE = 'pages' | 'app' @@ -1469,25 +1467,12 @@ export async function isPageStatic({ | undefined if (pageType === 'app') { - isClientComponent = isClientReference(componentsResult.ComponentMod) - const tree = componentsResult.ComponentMod.tree - - const staticGenerationAsyncStorage: StaticGenerationAsyncStorage = - componentsResult.ComponentMod.staticGenerationAsyncStorage - if (!staticGenerationAsyncStorage) { - throw new Error( - 'Invariant: staticGenerationAsyncStorage should be defined on the module' - ) - } + const ComponentMod: AppPageModule = componentsResult.ComponentMod - const serverHooks = componentsResult.ComponentMod.serverHooks - if (!serverHooks) { - throw new Error( - 'Invariant: serverHooks should be defined on the module' - ) - } + isClientComponent = isClientReference(componentsResult.ComponentMod) - const { routeModule } = componentsResult + const { tree, staticGenerationAsyncStorage, serverHooks, routeModule } = + ComponentMod const generateParams: GenerateParams = routeModule && AppRouteRouteModule.is(routeModule) diff --git a/packages/next/src/build/webpack/loaders/next-app-loader.ts b/packages/next/src/build/webpack/loaders/next-app-loader.ts index 017536bbc73d..69e97eb0812a 100644 --- a/packages/next/src/build/webpack/loaders/next-app-loader.ts +++ b/packages/next/src/build/webpack/loaders/next-app-loader.ts @@ -1,4 +1,4 @@ -import type webpack from 'webpack' +import type webpack from 'next/dist/compiled/webpack/webpack' import type { ValueOf } from '../../../shared/lib/constants' import type { ModuleReference, CollectedMetadata } from './metadata/types' diff --git a/packages/next/src/server/app-render/app-render.tsx b/packages/next/src/server/app-render/app-render.tsx index 7245a38e788c..fcc5089e693c 100644 --- a/packages/next/src/server/app-render/app-render.tsx +++ b/packages/next/src/server/app-render/app-render.tsx @@ -10,9 +10,6 @@ import type { RenderOpts, Segment, } from './types' -import type { StaticGenerationAsyncStorage } from '../../client/components/static-generation-async-storage.external' -import type { StaticGenerationBailout } from '../../client/components/static-generation-bailout' -import type { RequestAsyncStorage } from '../../client/components/request-async-storage.external' import React from 'react' import { createServerComponentRenderer } from './create-server-components-renderer' @@ -237,6 +234,7 @@ export const renderToHTMLOrFlight: AppPageRender = ( }) patchFetch(ComponentMod) + /** * Rules of Static & Dynamic HTML: * @@ -252,12 +250,25 @@ export const renderToHTMLOrFlight: AppPageRender = ( */ const generateStaticHTML = supportsDynamicHTML !== true - const staticGenerationAsyncStorage: StaticGenerationAsyncStorage = - ComponentMod.staticGenerationAsyncStorage - const requestAsyncStorage: RequestAsyncStorage = - ComponentMod.requestAsyncStorage - const staticGenerationBailout: StaticGenerationBailout = - ComponentMod.staticGenerationBailout + // Pull out the hooks/references from the component. + const { + staticGenerationAsyncStorage, + requestAsyncStorage, + staticGenerationBailout, + LayoutRouter, + RenderFromTemplateContext, + createSearchParamsBailoutProxy, + StaticGenerationSearchParamsBailoutProvider, + serverHooks: { DynamicServerError }, + NotFoundBoundary, + renderToReadableStream, + AppRouter, + GlobalError, + tree: loaderTree, + preloadFont, + preconnect, + preloadStyle, + } = ComponentMod // we wrap the render in an AsyncLocalStorage context const wrappedRender = async () => { @@ -294,11 +305,6 @@ export const renderToHTMLOrFlight: AppPageRender = ( ) : undefined - /** - * The tree created in next-app-loader that holds component segments and modules - */ - const loaderTree: LoaderTree = ComponentMod.tree - /** * The metadata items array created in next-app-loader with all relevant information * that we need to resolve the final metadata. @@ -312,15 +318,6 @@ export const renderToHTMLOrFlight: AppPageRender = ( requestId = require('next/dist/compiled/nanoid').nanoid() } - const LayoutRouter = - ComponentMod.LayoutRouter as typeof import('../../client/components/layout-router').default - const RenderFromTemplateContext = - ComponentMod.RenderFromTemplateContext as typeof import('../../client/components/render-from-template-context').default - const createSearchParamsBailoutProxy = - ComponentMod.createSearchParamsBailoutProxy as typeof import('../../client/components/searchparams-bailout-proxy').createSearchParamsBailoutProxy - const StaticGenerationSearchParamsBailoutProvider = - ComponentMod.StaticGenerationSearchParamsBailoutProvider as typeof import('../../client/components/static-generation-searchparams-bailout-provider').default - const isStaticGeneration = staticGenerationStore.isStaticGeneration // During static generation we need to call the static generation bailout when reading searchParams const providedSearchParams = isStaticGeneration @@ -511,16 +508,16 @@ export const renderToHTMLOrFlight: AppPageRender = ( const ext = /\.(woff|woff2|eot|ttf|otf)$/.exec(fontFilename)![1] const type = `font/${ext}` const href = `${assetPrefix}/_next/${fontFilename}` - ComponentMod.preloadFont(href, type, renderOpts.crossOrigin) + preloadFont(href, type, renderOpts.crossOrigin) } } else { try { let url = new URL(assetPrefix) - ComponentMod.preconnect(url.origin, 'anonymous') + preconnect(url.origin, 'anonymous') } catch (error) { // assetPrefix must not be a fully qualified domain name. We assume // we should preconnect to same origin instead - ComponentMod.preconnect('/', 'anonymous') + preconnect('/', 'anonymous') } } } @@ -546,7 +543,7 @@ export const renderToHTMLOrFlight: AppPageRender = ( const precedence = process.env.NODE_ENV === 'development' ? 'next_' + href : 'next' - ComponentMod.preloadStyle(fullHref, renderOpts.crossOrigin) + preloadStyle(fullHref, renderOpts.crossOrigin) return ( 1 if (hasSlotKey && rootLayoutAtThisLevel) { - const NotFoundBoundary = - ComponentMod.NotFoundBoundary as typeof import('../../client/components/not-found-boundary').NotFoundBoundary Component = (componentProps: any) => { const NotFoundComponent = NotFound const RootLayoutComponent = LayoutOrPage @@ -1287,7 +1279,7 @@ export const renderToHTMLOrFlight: AppPageRender = ( // For app dir, use the bundled version of Flight server renderer (renderToReadableStream) // which contains the subset React. - const flightReadableStream = ComponentMod.renderToReadableStream( + const flightReadableStream = renderToReadableStream( options ? [options.actionResult, buildIdFlightDataPair] : buildIdFlightDataPair, @@ -1305,16 +1297,6 @@ export const renderToHTMLOrFlight: AppPageRender = ( return generateFlight() } - // Below this line is handling for rendering to HTML. - - // AppRouter is provided by next-app-loader - const AppRouter = - ComponentMod.AppRouter as typeof import('../../client/components/app-router').default - - const GlobalError = - /** GlobalError can be either the default error boundary or the overwritten app/global-error.js **/ - ComponentMod.GlobalError as typeof import('../../client/components/error-boundary').GlobalError - // Get the nonce from the incoming request if it has one. const csp = req.headers['content-security-policy'] let nonce: string | undefined diff --git a/packages/next/src/server/app-render/create-server-components-renderer.tsx b/packages/next/src/server/app-render/create-server-components-renderer.tsx index 2b4321cfbf24..d88f5492c61d 100644 --- a/packages/next/src/server/app-render/create-server-components-renderer.tsx +++ b/packages/next/src/server/app-render/create-server-components-renderer.tsx @@ -1,5 +1,6 @@ import type { RenderOpts } from './types' import type { FlightResponseRef } from './flight-response-ref' +import type { AppPageModule } from '../future/route-modules/app-page/module' import React, { use } from 'react' import { createErrorHandler } from './create-error-handler' @@ -11,13 +12,7 @@ import { useFlightResponse } from './use-flight-response' */ export function createServerComponentRenderer( ComponentToRender: (props: Props) => any, - ComponentMod: { - renderToReadableStream: any - __next_app__?: { - require: any - loadChunk: any - } - }, + ComponentMod: AppPageModule, { inlinedDataTransformStream, clientReferenceManifest, diff --git a/packages/next/src/server/app-render/entry-base.ts b/packages/next/src/server/app-render/entry-base.ts index aeb65ba62125..ae7e186764a4 100644 --- a/packages/next/src/server/app-render/entry-base.ts +++ b/packages/next/src/server/app-render/entry-base.ts @@ -1,10 +1,10 @@ -const { +export { renderToReadableStream, decodeReply, decodeAction, decodeFormState, // eslint-disable-next-line import/no-extraneous-dependencies -} = require('react-server-dom-webpack/server.edge') +} from 'react-server-dom-webpack/server.edge' import AppRouter from '../../client/components/app-router' import LayoutRouter from '../../client/components/layout-router' @@ -36,10 +36,6 @@ export { staticGenerationBailout, createSearchParamsBailoutProxy, serverHooks, - renderToReadableStream, - decodeReply, - decodeAction, - decodeFormState, preloadStyle, preloadFont, preconnect, diff --git a/packages/next/src/server/app-render/types.ts b/packages/next/src/server/app-render/types.ts index 085b63629b4c..59d23ef98243 100644 --- a/packages/next/src/server/app-render/types.ts +++ b/packages/next/src/server/app-render/types.ts @@ -1,9 +1,10 @@ import type { LoadComponentsReturnType } from '../load-components' import type { ServerRuntime, SizeLimit } from '../../../types' -import { NextConfigComplete } from '../../server/config-shared' +import type { NextConfigComplete } from '../../server/config-shared' import type { ClientReferenceManifest } from '../../build/webpack/plugins/flight-manifest-plugin' import type { NextFontManifest } from '../../build/webpack/plugins/next-font-manifest-plugin' import type { ParsedUrlQuery } from 'querystring' +import type { AppPageModule } from '../future/route-modules/app-page/module' import s from 'next/dist/compiled/superstruct' @@ -135,4 +136,5 @@ export interface RenderOptsPartial { isPrefetch?: boolean } -export type RenderOpts = LoadComponentsReturnType & RenderOptsPartial +export type RenderOpts = LoadComponentsReturnType & + RenderOptsPartial diff --git a/packages/next/src/server/future/route-modules/app-page/module.compiled.d.ts b/packages/next/src/server/future/route-modules/app-page/module.compiled.d.ts new file mode 100644 index 000000000000..5401340695ab --- /dev/null +++ b/packages/next/src/server/future/route-modules/app-page/module.compiled.d.ts @@ -0,0 +1 @@ +export * from './module' diff --git a/packages/next/src/server/future/route-modules/app-page/module.compiled.ts b/packages/next/src/server/future/route-modules/app-page/module.compiled.js similarity index 100% rename from packages/next/src/server/future/route-modules/app-page/module.compiled.ts rename to packages/next/src/server/future/route-modules/app-page/module.compiled.js diff --git a/packages/next/src/server/future/route-modules/app-page/module.ts b/packages/next/src/server/future/route-modules/app-page/module.ts index 5a34be6759ad..0c5e7cbcb17d 100644 --- a/packages/next/src/server/future/route-modules/app-page/module.ts +++ b/packages/next/src/server/future/route-modules/app-page/module.ts @@ -22,6 +22,13 @@ if (process.env.NEXT_RUNTIME !== 'edge') { vendoredReactSSR = require('./vendored/ssr/entrypoints') } +/** + * The AppPageModule is the type of the module exported by the bundled app page + * module. + */ +export type AppPageModule = + typeof import('../../../../build/templates/app-page') + type AppPageUserlandModule = { /** * The tree created in next-app-loader that holds component segments and modules diff --git a/packages/next/src/server/future/route-modules/app-route/module.compiled.d.ts b/packages/next/src/server/future/route-modules/app-route/module.compiled.d.ts new file mode 100644 index 000000000000..5401340695ab --- /dev/null +++ b/packages/next/src/server/future/route-modules/app-route/module.compiled.d.ts @@ -0,0 +1 @@ +export * from './module' diff --git a/packages/next/src/server/future/route-modules/app-route/module.compiled.ts b/packages/next/src/server/future/route-modules/app-route/module.compiled.js similarity index 100% rename from packages/next/src/server/future/route-modules/app-route/module.compiled.ts rename to packages/next/src/server/future/route-modules/app-route/module.compiled.js diff --git a/packages/next/src/server/future/route-modules/app-route/module.ts b/packages/next/src/server/future/route-modules/app-route/module.ts index 41ea0ea87f06..4caf96f791a5 100644 --- a/packages/next/src/server/future/route-modules/app-route/module.ts +++ b/packages/next/src/server/future/route-modules/app-route/module.ts @@ -44,6 +44,13 @@ import { staticGenerationAsyncStorage } from '../../../../client/components/stat import { actionAsyncStorage } from '../../../../client/components/action-async-storage.external' import * as sharedModules from './shared-modules' +/** + * The AppRouteModule is the type of the module exported by the bundled App + * Route module. + */ +export type AppRouteModule = + typeof import('../../../../build/templates/app-route') + /** * AppRouteRouteHandlerContext is the context that is passed to the route * handler for app routes. diff --git a/packages/next/src/server/future/route-modules/pages-api/module.compiled.d.ts b/packages/next/src/server/future/route-modules/pages-api/module.compiled.d.ts new file mode 100644 index 000000000000..5401340695ab --- /dev/null +++ b/packages/next/src/server/future/route-modules/pages-api/module.compiled.d.ts @@ -0,0 +1 @@ +export * from './module' diff --git a/packages/next/src/server/future/route-modules/pages-api/module.compiled.ts b/packages/next/src/server/future/route-modules/pages-api/module.compiled.js similarity index 100% rename from packages/next/src/server/future/route-modules/pages-api/module.compiled.ts rename to packages/next/src/server/future/route-modules/pages-api/module.compiled.js diff --git a/packages/next/src/server/future/route-modules/pages-api/module.ts b/packages/next/src/server/future/route-modules/pages-api/module.ts index 4f9c4fe5749c..70940f443172 100644 --- a/packages/next/src/server/future/route-modules/pages-api/module.ts +++ b/packages/next/src/server/future/route-modules/pages-api/module.ts @@ -16,6 +16,13 @@ type PagesAPIHandleFn = ( res: ServerResponse ) => Promise +/** + * The PagesAPIModule is the type of the module exported by the bundled Pages + * API module. + */ +export type PagesAPIModule = + typeof import('../../../../build/templates/pages-api') + type PagesAPIUserlandModule = { /** * The exported handler method. diff --git a/packages/next/src/server/future/route-modules/pages/module.compiled.d.ts b/packages/next/src/server/future/route-modules/pages/module.compiled.d.ts new file mode 100644 index 000000000000..5401340695ab --- /dev/null +++ b/packages/next/src/server/future/route-modules/pages/module.compiled.d.ts @@ -0,0 +1 @@ +export * from './module' diff --git a/packages/next/src/server/future/route-modules/pages/module.compiled.ts b/packages/next/src/server/future/route-modules/pages/module.compiled.js similarity index 100% rename from packages/next/src/server/future/route-modules/pages/module.compiled.ts rename to packages/next/src/server/future/route-modules/pages/module.compiled.js diff --git a/packages/next/src/server/future/route-modules/pages/module.ts b/packages/next/src/server/future/route-modules/pages/module.ts index 3abbe1da064e..c50b9c3eb718 100644 --- a/packages/next/src/server/future/route-modules/pages/module.ts +++ b/packages/next/src/server/future/route-modules/pages/module.ts @@ -20,6 +20,12 @@ import { import { renderToHTMLImpl, renderToHTML } from '../../../render' import * as vendoredContexts from './vendored/contexts/entrypoints' +/** + * The PagesModule is the type of the module exported by the bundled pages + * module. + */ +export type PagesModule = typeof import('../../../../build/templates/pages') + /** * The userland module for a page. This is the module that is exported from the * page file that contains the page component, page config, and any page data diff --git a/packages/next/src/server/lib/patch-fetch.ts b/packages/next/src/server/lib/patch-fetch.ts index 7f250860f51f..2e1b23a24172 100644 --- a/packages/next/src/server/lib/patch-fetch.ts +++ b/packages/next/src/server/lib/patch-fetch.ts @@ -141,15 +141,17 @@ function trackFetchMetric( }) } +interface PatchableModule { + serverHooks: typeof ServerHooks + staticGenerationAsyncStorage: StaticGenerationAsyncStorage +} + // we patch fetch to collect cache information used for // determining if a page is static or not export function patchFetch({ serverHooks, staticGenerationAsyncStorage, -}: { - serverHooks: typeof ServerHooks - staticGenerationAsyncStorage: StaticGenerationAsyncStorage -}) { +}: PatchableModule) { if (!(globalThis as any)._nextOriginalFetch) { ;(globalThis as any)._nextOriginalFetch = globalThis.fetch } diff --git a/packages/next/src/server/load-components.ts b/packages/next/src/server/load-components.ts index eb53b2736db6..042b3788e989 100644 --- a/packages/next/src/server/load-components.ts +++ b/packages/next/src/server/load-components.ts @@ -33,7 +33,7 @@ export type ManifestItem = { export type ReactLoadableManifest = { [moduleId: string]: ManifestItem } -export type LoadComponentsReturnType = { +export type LoadComponentsReturnType = { Component: NextComponentType pageConfig: PageConfig buildManifest: BuildManifest @@ -46,7 +46,7 @@ export type LoadComponentsReturnType = { getStaticProps?: GetStaticProps getStaticPaths?: GetStaticPaths getServerSideProps?: GetServerSideProps - ComponentMod: any + ComponentMod: NextModule routeModule?: RouteModule isAppPath?: boolean page: string @@ -88,7 +88,7 @@ async function loadClientReferenceManifest( } } -async function loadComponentsImpl({ +async function loadComponentsImpl({ distDir, page, isAppPath, @@ -96,7 +96,7 @@ async function loadComponentsImpl({ distDir: string page: string isAppPath: boolean -}): Promise { +}): Promise> { let DocumentMod = {} let AppMod = {} if (!isAppPath) { diff --git a/packages/next/src/server/render.tsx b/packages/next/src/server/render.tsx index f23df5d7cf84..a67ba29583d5 100644 --- a/packages/next/src/server/render.tsx +++ b/packages/next/src/server/render.tsx @@ -34,6 +34,7 @@ import type { UnwrapPromise } from '../lib/coalesced-function' import type { ReactReadableStream } from './stream-utils/node-web-streams-helper' import type { ClientReferenceManifest } from '../build/webpack/plugins/flight-manifest-plugin' import type { NextFontManifest } from '../build/webpack/plugins/next-font-manifest-plugin' +import type { PagesModule } from './future/route-modules/pages/module' import React from 'react' import ReactDOMServer from 'react-dom/server.browser' @@ -286,7 +287,8 @@ export type RenderOptsPartial = { isPrefetch?: boolean } -export type RenderOpts = LoadComponentsReturnType & RenderOptsPartial +export type RenderOpts = LoadComponentsReturnType & + RenderOptsPartial /** * RenderOptsExtra is being used to split away functionality that's within the diff --git a/packages/next/types/compiled.d.ts b/packages/next/types/compiled.d.ts index e53f2a5d2657..7d6707c1e657 100644 --- a/packages/next/types/compiled.d.ts +++ b/packages/next/types/compiled.d.ts @@ -8,6 +8,8 @@ declare module 'next/dist/compiled/webpack/webpack' { export let GraphHelpers: any export let sources: any export let StringXor: any + // eslint-disable-next-line @typescript-eslint/no-unused-vars + export type LoaderDefinitionFunction = any namespace webpack { export type Compiler = any export type WebpackPluginInstance = any @@ -44,3 +46,10 @@ declare module 'next/dist/compiled/superstruct' { // eslint-disable-next-line @typescript-eslint/no-unused-vars export type Describe = any } + +declare module 'react-server-dom-webpack/server.edge' + +declare module 'VAR_MODULE_GLOBAL_ERROR' +declare module 'VAR_USERLAND' +declare module 'VAR_MODULE_DOCUMENT' +declare module 'VAR_MODULE_APP' diff --git a/packages/next/types/misc.d.ts b/packages/next/types/misc.d.ts index f3c438e780ad..00633f5acfc7 100644 --- a/packages/next/types/misc.d.ts +++ b/packages/next/types/misc.d.ts @@ -35,6 +35,11 @@ declare module 'react-dom/server-rendering-stub' declare module 'react-dom/server.browser' declare module 'react-dom/server.edge' +declare module 'VAR_MODULE_GLOBAL_ERROR' +declare module 'VAR_USERLAND' +declare module 'VAR_MODULE_DOCUMENT' +declare module 'VAR_MODULE_APP' + declare module 'next/dist/compiled/@next/react-dev-overlay/dist/client' { export * from '@next/react-dev-overlay/dist/client' } diff --git a/packages/next/types/webpack.d.ts b/packages/next/types/webpack.d.ts index caba6a1b1688..64e68d48e904 100644 --- a/packages/next/types/webpack.d.ts +++ b/packages/next/types/webpack.d.ts @@ -34,6 +34,7 @@ declare module 'next/dist/compiled/webpack/webpack' { export let sources: typeof webpackSources export let StringXor: any export { + default as webpack, Compiler, Compilation, Module, @@ -43,6 +44,8 @@ declare module 'next/dist/compiled/webpack/webpack' { RuntimeGlobals, NormalModule, ResolvePluginInstance, + ModuleFilenameHelpers, + LoaderDefinitionFunction, + LoaderContext, } from 'webpack' - export { default as webpack, ModuleFilenameHelpers } from 'webpack' }