From 4392b6a9fa09455bf6a733bd9a9c2d578cf62c66 Mon Sep 17 00:00:00 2001 From: Shu Ding Date: Thu, 28 Apr 2022 18:16:51 +0200 Subject: [PATCH] Refactor base server to get rid of the __server_context hack (#36550) This PR makes the `Options` type of base server configurable as well as assigning to `this.serverOptions`, so the web server can access it during `constructor()`. This gets rid of the dirty `__server_context` hack. ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have helpful link attached, see `contributing.md` ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have helpful link attached, see `contributing.md` ## Documentation / Examples - [ ] Make sure the linting passes by running `yarn lint` --- .../next-middleware-ssr-loader/index.ts | 6 ---- .../next-middleware-ssr-loader/render.ts | 1 + packages/next/server/base-server.ts | 26 +++++++++-------- packages/next/server/web-server.ts | 28 +++++++++++-------- 4 files changed, 33 insertions(+), 28 deletions(-) diff --git a/packages/next/build/webpack/loaders/next-middleware-ssr-loader/index.ts b/packages/next/build/webpack/loaders/next-middleware-ssr-loader/index.ts index 1297d01566b27..6f88f41b71022 100644 --- a/packages/next/build/webpack/loaders/next-middleware-ssr-loader/index.ts +++ b/packages/next/build/webpack/loaders/next-middleware-ssr-loader/index.ts @@ -64,12 +64,6 @@ export default async function middlewareSSRLoader(this: any) { const reactLoadableManifest = self.__REACT_LOADABLE_MANIFEST const rscManifest = self.__RSC_MANIFEST - // Set server context - self.__server_context = { - page: ${JSON.stringify(page)}, - buildId: ${JSON.stringify(buildId)}, - } - const render = getRender({ dev: ${dev}, page: ${JSON.stringify(page)}, diff --git a/packages/next/build/webpack/loaders/next-middleware-ssr-loader/render.ts b/packages/next/build/webpack/loaders/next-middleware-ssr-loader/render.ts index 1bb978309b0d3..341334e3d4d5d 100644 --- a/packages/next/build/webpack/loaders/next-middleware-ssr-loader/render.ts +++ b/packages/next/build/webpack/loaders/next-middleware-ssr-loader/render.ts @@ -57,6 +57,7 @@ export function getRender({ conf: config, minimalMode: true, webServerConfig: { + page, extendRenderOpts: { buildId, reactRoot: true, diff --git a/packages/next/server/base-server.ts b/packages/next/server/base-server.ts index 9412b21f4386e..1d76fa5df548e 100644 --- a/packages/next/server/base-server.ts +++ b/packages/next/server/base-server.ts @@ -128,7 +128,7 @@ type RequestContext = { renderOpts: RenderOptsPartial } -export default abstract class Server { +export default abstract class Server { protected dir: string protected quiet: boolean protected nextConfig: NextConfigComplete @@ -171,6 +171,7 @@ export default abstract class Server { serverComponentProps?: any reactRoot: boolean } + protected serverOptions: ServerOptions private incrementalCache: IncrementalCache private responseCache: ResponseCache protected router: Router @@ -261,16 +262,19 @@ export default abstract class Server { protected abstract loadEnvConfig(params: { dev: boolean }): void - public constructor({ - dir = '.', - quiet = false, - conf, - dev = false, - minimalMode = false, - customServer = true, - hostname, - port, - }: Options) { + public constructor(options: ServerOptions) { + const { + dir = '.', + quiet = false, + conf, + dev = false, + minimalMode = false, + customServer = true, + hostname, + port, + } = options + this.serverOptions = options + this.dir = resolve(dir) this.quiet = quiet this.loadEnvConfig({ dev }) diff --git a/packages/next/server/web-server.ts b/packages/next/server/web-server.ts index d70a49191ef33..1ae3386768df7 100644 --- a/packages/next/server/web-server.ts +++ b/packages/next/server/web-server.ts @@ -11,18 +11,22 @@ import BaseServer from './base-server' import { renderToHTML } from './render' import { byteLength, generateETag } from './api-utils/web' -interface WebServerConfig { - loadComponent: (pathname: string) => Promise - extendRenderOpts?: Partial +interface WebServerOptions extends Options { + webServerConfig: { + page: string + loadComponent: ( + pathname: string + ) => Promise + extendRenderOpts: Partial & + Pick + } } -export default class NextWebServer extends BaseServer { - webServerConfig: WebServerConfig - - constructor(options: Options & { webServerConfig: WebServerConfig }) { +export default class NextWebServer extends BaseServer { + constructor(options: WebServerOptions) { super(options) - this.webServerConfig = options.webServerConfig + // Extend `renderOpts`. Object.assign(this.renderOpts, options.webServerConfig.extendRenderOpts) } @@ -58,7 +62,7 @@ export default class NextWebServer extends BaseServer { return '' } protected getBuildId() { - return (globalThis as any).__server_context.buildId + return this.serverOptions.webServerConfig.extendRenderOpts.buildId } protected loadEnvConfig() { // The web server does not need to load the env config. This is done by the @@ -96,7 +100,7 @@ export default class NextWebServer extends BaseServer { } protected getPagesManifest() { return { - [(globalThis as any).__server_context.page]: '', + [this.serverOptions.webServerConfig.page]: '', } } protected getFilesystemPaths() { @@ -199,7 +203,9 @@ export default class NextWebServer extends BaseServer { query?: NextParsedUrlQuery, params?: Params | null ) { - const result = await this.webServerConfig.loadComponent(pathname) + const result = await this.serverOptions.webServerConfig.loadComponent( + pathname + ) if (!result) return null return {