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

Eliminate path polyfill and incremental-cache from base server #39548

Merged
merged 6 commits into from Aug 12, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 4 additions & 2 deletions packages/next/build/webpack-config.ts
Expand Up @@ -7,8 +7,6 @@ import path, { dirname, join as pathJoin, relative as relativePath } from 'path'
import { escapeStringRegexp } from '../shared/lib/escape-regexp'
import {
DOT_NEXT_ALIAS,
NEXT_PROJECT_ROOT,
NEXT_PROJECT_ROOT_DIST_CLIENT,
PAGES_DIR_ALIAS,
ROOT_DIR_ALIAS,
APP_DIR_ALIAS,
Expand Down Expand Up @@ -64,6 +62,10 @@ import { loadBindings } from './swc'
import { clientComponentRegex } from './webpack/loaders/utils'
import { AppBuildManifestPlugin } from './webpack/plugins/app-build-manifest-plugin'

const NEXT_PROJECT_ROOT = pathJoin(__dirname, '..', '..')
const NEXT_PROJECT_ROOT_DIST = pathJoin(NEXT_PROJECT_ROOT, 'dist')
const NEXT_PROJECT_ROOT_DIST_CLIENT = pathJoin(NEXT_PROJECT_ROOT_DIST, 'client')

const watchOptions = Object.freeze({
aggregateTimeout: 5,
ignored: ['**/.git/**', '**/.next/**'],
Expand Down
8 changes: 0 additions & 8 deletions packages/next/lib/constants.ts
@@ -1,12 +1,4 @@
import type { ServerRuntime } from '../types'
import { join } from '../shared/lib/isomorphic/path'

export const NEXT_PROJECT_ROOT = join(__dirname, '..', '..')
export const NEXT_PROJECT_ROOT_DIST = join(NEXT_PROJECT_ROOT, 'dist')
export const NEXT_PROJECT_ROOT_DIST_CLIENT = join(
NEXT_PROJECT_ROOT_DIST,
'client'
)

// Regex for API routes
export const API_ROUTE = /^\/api(?:\/|$)/
Expand Down
61 changes: 20 additions & 41 deletions packages/next/server/base-server.ts
Expand Up @@ -10,7 +10,11 @@ import type { NextConfig, NextConfigComplete } from './config-shared'
import type { NextParsedUrlQuery, NextUrlWithParsedQuery } from './request-meta'
import type { ParsedUrlQuery } from 'querystring'
import type { RenderOpts, RenderOptsPartial } from './render'
import type { ResponseCacheEntry, ResponseCacheValue } from './response-cache'
import type {
ResponseCacheBase,
ResponseCacheEntry,
ResponseCacheValue,
} from './response-cache'
import type { UrlWithParsedQuery } from 'url'
import {
CacheFs,
Expand All @@ -24,7 +28,7 @@ import type { PagesManifest } from '../build/webpack/plugins/pages-manifest-plug
import type { BaseNextRequest, BaseNextResponse } from './base-http'
import type { PayloadOptions } from './send-payload'

import { join, resolve } from '../shared/lib/isomorphic/path'
import { join } from '../shared/lib/isomorphic/path'
import { parse as parseQs } from 'querystring'
import { format as formatUrl, parse as parseUrl } from 'url'
import { getRedirectStatus } from '../lib/redirect-status'
Expand All @@ -46,7 +50,6 @@ import { isTargetLikeServerless } from './utils'
import Router from './router'
import { getPathMatch } from '../shared/lib/router/utils/path-match'
import { setRevalidateHeaders } from './send-payload/revalidate-headers'
import { IncrementalCache } from './lib/incremental-cache'
import { execOnce } from '../shared/lib/utils'
import { isBlockedPage, isBot } from './utils'
import RenderResult from './render-result'
Expand All @@ -58,7 +61,6 @@ import * as Log from '../build/output/log'
import { detectDomainLocale } from '../shared/lib/i18n/detect-domain-locale'
import escapePathDelimiters from '../shared/lib/router/utils/escape-path-delimiters'
import { getUtils } from '../build/webpack/loaders/next-serverless-loader/utils'
import ResponseCache from './response-cache'
import isError, { getProperError } from '../lib/is-error'
import { addRequestMeta, getRequestMeta } from './request-meta'
import { createHeaderRoute, createRedirectRoute } from './server-route-utils'
Expand All @@ -72,7 +74,6 @@ import { getLocaleRedirect } from '../shared/lib/i18n/get-locale-redirect'
import { getHostname } from '../shared/lib/get-hostname'
import { parseUrl as parseUrlUtil } from '../shared/lib/router/utils/parse-url'
import { getNextPathnameInfo } from '../shared/lib/router/utils/get-next-pathname-info'
import { normalizePagePath } from '../shared/lib/page-path/normalize-page-path'

export type FindComponentsResult = {
components: LoadComponentsReturnType
Expand Down Expand Up @@ -203,8 +204,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
largePageDataBytes?: number
}
protected serverOptions: ServerOptions
private incrementalCache: IncrementalCache
private responseCache: ResponseCache
private responseCache: ResponseCacheBase
protected router: Router
protected dynamicRoutes?: DynamicRoutes
protected appPathRoutes?: Record<string, string>
Expand Down Expand Up @@ -250,6 +250,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
req: BaseNextRequest,
parsedUrl: NextUrlWithParsedQuery
): void
protected abstract getFallback(page: string): Promise<string>

protected abstract sendRenderResult(
req: BaseNextRequest,
Expand Down Expand Up @@ -285,6 +286,10 @@ export default abstract class Server<ServerOptions extends Options = Options> {
res: BaseNextResponse
): void

protected abstract getResponseCache(options: {
dev: boolean
}): ResponseCacheBase

protected abstract loadEnvConfig(params: {
dev: boolean
forceReload?: boolean
Expand All @@ -303,7 +308,9 @@ export default abstract class Server<ServerOptions extends Options = Options> {
} = options
this.serverOptions = options

this.dir = resolve(dir)
this.dir =
process.env.NEXT_RUNTIME === 'edge' ? dir : require('path').resolve(dir)

this.quiet = quiet
this.loadEnvConfig({ dev })

Expand All @@ -312,7 +319,10 @@ export default abstract class Server<ServerOptions extends Options = Options> {
this.nextConfig = conf as NextConfigComplete
this.hostname = hostname
this.port = port
this.distDir = join(this.dir, this.nextConfig.distDir)
this.distDir =
process.env.NEXT_RUNTIME === 'edge'
? this.nextConfig.distDir
: require('path').join(this.dir, this.nextConfig.distDir)
this.publicDir = this.getPublicDir()
this.hasStaticDir = !minimalMode && this.getHasStaticDir()

Expand Down Expand Up @@ -385,32 +395,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
this.router = new Router(this.generateRoutes())
this.setAssetPrefix(assetPrefix)

this.incrementalCache = new IncrementalCache({
fs: this.getCacheFilesystem(),
dev,
serverDistDir: this.serverDistDir,
maxMemoryCacheSize: this.nextConfig.experimental.isrMemoryCacheSize,
flushToDisk: !minimalMode && this.nextConfig.experimental.isrFlushToDisk,
incrementalCacheHandlerPath:
this.nextConfig.experimental?.incrementalCacheHandlerPath,
getPrerenderManifest: () => {
if (dev) {
return {
version: -1 as any, // letting us know this doesn't conform to spec
routes: {},
dynamicRoutes: {},
notFoundRoutes: [],
preview: null as any, // `preview` is special case read in next-dev-server
}
} else {
return this.getPrerenderManifest()
}
},
})
this.responseCache = new ResponseCache(
this.incrementalCache,
this.minimalMode
)
this.responseCache = this.getResponseCache({ dev })
}

public logError(err: Error): void {
Expand Down Expand Up @@ -730,12 +715,6 @@ export default abstract class Server<ServerOptions extends Options = Options> {
return Object.assign(customRoutes, { rewrites })
}

protected getFallback(page: string): Promise<string> {
page = normalizePagePath(page)
const cacheFs = this.getCacheFilesystem()
return cacheFs.readFile(join(this.serverDistDir, 'pages', `${page}.html`))
}

protected getPreviewProps(): __ApiPreviewProps {
return this.getPrerenderManifest().preview
}
Expand Down
37 changes: 36 additions & 1 deletion packages/next/server/next-server.ts
Expand Up @@ -80,13 +80,14 @@ import { getRouteMatcher } from '../shared/lib/router/utils/route-matcher'
import { loadEnvConfig } from '@next/env'
import { getCustomRoute } from './server-route-utils'
import { urlQueryToSearchParams } from '../shared/lib/router/utils/querystring'
import ResponseCache from '../server/response-cache'
import { removeTrailingSlash } from '../shared/lib/router/utils/remove-trailing-slash'
import { getNextPathnameInfo } from '../shared/lib/router/utils/get-next-pathname-info'
import { bodyStreamToNodeStream, getClonableBody } from './body-streams'
import { checkIsManualRevalidate } from './api-utils'
import { isDynamicRoute } from '../shared/lib/router/utils'
import { shouldUseReactRoot } from './utils'
import ResponseCache from './response-cache'
import { IncrementalCache } from './lib/incremental-cache'

if (shouldUseReactRoot) {
;(process.env as any).__NEXT_REACT_ROOT = 'true'
Expand Down Expand Up @@ -171,6 +172,34 @@ export default class NextNodeServer extends BaseServer {
loadEnvConfig(this.dir, dev, Log, forceReload)
}

protected getResponseCache({ dev }: { dev: boolean }) {
const incrementalCache = new IncrementalCache({
fs: this.getCacheFilesystem(),
dev,
serverDistDir: this.serverDistDir,
maxMemoryCacheSize: this.nextConfig.experimental.isrMemoryCacheSize,
flushToDisk:
!this.minimalMode && this.nextConfig.experimental.isrFlushToDisk,
incrementalCacheHandlerPath:
this.nextConfig.experimental?.incrementalCacheHandlerPath,
getPrerenderManifest: () => {
if (dev) {
return {
version: -1 as any, // letting us know this doesn't conform to spec
routes: {},
dynamicRoutes: {},
notFoundRoutes: [],
preview: null as any, // `preview` is special case read in next-dev-server
}
} else {
return this.getPrerenderManifest()
}
},
})

return new ResponseCache(incrementalCache, this.minimalMode)
}

protected getPublicDir(): string {
return join(this.dir, CLIENT_PUBLIC_FILES_PATH)
}
Expand Down Expand Up @@ -798,6 +827,12 @@ export default class NextNodeServer extends BaseServer {
))
}

protected getFallback(page: string): Promise<string> {
page = normalizePagePath(page)
const cacheFs = this.getCacheFilesystem()
return cacheFs.readFile(join(this.serverDistDir, 'pages', `${page}.html`))
}

protected getCacheFilesystem(): CacheFs {
return {
readFile: (f) => fs.promises.readFile(f, 'utf8'),
Expand Down
@@ -1,82 +1,13 @@
import RenderResult from './render-result'
import type {
IncrementalCache,
ResponseCacheEntry,
ResponseGenerator,
IncrementalCacheItem,
} from './types'

export interface CachedRedirectValue {
kind: 'REDIRECT'
props: Object
}

interface CachedPageValue {
kind: 'PAGE'
// this needs to be a RenderResult so since renderResponse
// expects that type instead of a string
html: RenderResult
pageData: Object
}

export interface CachedImageValue {
kind: 'IMAGE'
etag: string
buffer: Buffer
extension: string
isMiss?: boolean
isStale?: boolean
}

interface IncrementalCachedPageValue {
kind: 'PAGE'
// this needs to be a string since the cache expects to store
// the string value
html: string
pageData: Object
}

export type IncrementalCacheEntry = {
curRevalidate?: number | false
// milliseconds to revalidate after
revalidateAfter: number | false
isStale?: boolean
value: IncrementalCacheValue | null
}

export type IncrementalCacheValue =
| CachedRedirectValue
| IncrementalCachedPageValue
| CachedImageValue

export type ResponseCacheValue =
| CachedRedirectValue
| CachedPageValue
| CachedImageValue

export type ResponseCacheEntry = {
revalidate?: number | false
value: ResponseCacheValue | null
isStale?: boolean
isMiss?: boolean
}

type ResponseGenerator = (
hasResolved: boolean,
hadCache: boolean
) => Promise<ResponseCacheEntry | null>
import RenderResult from '../render-result'

type IncrementalCacheItem = {
revalidateAfter?: number | false
curRevalidate?: number | false
revalidate?: number | false
value: IncrementalCacheValue | null
isStale?: boolean
isMiss?: boolean
} | null

interface IncrementalCache {
get: (key: string) => Promise<IncrementalCacheItem>
set: (
key: string,
data: IncrementalCacheValue | null,
revalidate?: number | false
) => Promise<void>
}
export * from './types'

export default class ResponseCache {
incrementalCache: IncrementalCache
Expand Down