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

Use edge compiler for middleware #36486

Merged
merged 7 commits into from Apr 27, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
493 changes: 251 additions & 242 deletions packages/next/build/entries.ts

Large diffs are not rendered by default.

130 changes: 53 additions & 77 deletions packages/next/build/index.ts
Expand Up @@ -15,6 +15,7 @@ import {
STATIC_STATUS_PAGE_GET_INITIAL_PROPS_ERROR,
PUBLIC_DIR_MIDDLEWARE_CONFLICT,
MIDDLEWARE_ROUTE,
PAGES_DIR_ALIAS,
} from '../lib/constants'
import { fileExists } from '../lib/file-exists'
import { findPagesDir } from '../lib/find-pages-dir'
Expand Down Expand Up @@ -88,7 +89,6 @@ import * as Log from './output/log'
import createSpinner from './spinner'
import { trace, flushAllTraces, setGlobal } from '../trace'
import {
collectPages,
detectConflictingPaths,
computeFromManifest,
getJsPageSizeInKb,
Expand All @@ -112,6 +112,7 @@ import { MiddlewareManifest } from './webpack/plugins/middleware-plugin'
import type { webpack5 as webpack } from 'next/dist/compiled/webpack/webpack'
import { recursiveCopy } from '../lib/recursive-copy'
import { shouldUseReactRoot } from '../server/config'
import { recursiveReadDir } from '../lib/recursive-readdir'

export type SsgRoute = {
initialRevalidateSeconds: number | false
Expand Down Expand Up @@ -283,9 +284,14 @@ export default async function build(

const isLikeServerless = isTargetLikeServerless(target)

const pagePaths: string[] = await nextBuildSpan
const pagePaths = await nextBuildSpan
.traceChild('collect-pages')
.traceAsyncFn(() => collectPages(pagesDir, config.pageExtensions))
.traceAsyncFn(() =>
recursiveReadDir(
pagesDir,
new RegExp(`\\.(?:${config.pageExtensions.join('|')})$`)
)
)
// needed for static exporting since we want to replace with HTML
// files

Expand All @@ -301,37 +307,36 @@ export default async function build(
const mappedPages = nextBuildSpan
.traceChild('create-pages-mapping')
.traceFn(() =>
createPagesMapping(pagePaths, config.pageExtensions, {
isDev: false,
createPagesMapping({
hasServerComponents,
isDev: false,
pageExtensions: config.pageExtensions,
pagePaths,
})
)

const entrypoints = await nextBuildSpan
.traceChild('create-entrypoints')
.traceAsyncFn(() =>
createEntrypoints(
mappedPages,
target,
createEntrypoints({
buildId,
previewProps,
config,
loadedEnvFiles,
envFiles: loadedEnvFiles,
isDev: false,
pages: mappedPages,
pagesDir,
false
)
previewMode: previewProps,
target,
})
)

const pageKeys = Object.keys(mappedPages)
const hasMiddleware = pageKeys.some((page) => MIDDLEWARE_ROUTE.test(page))
const conflictingPublicFiles: string[] = []
const hasCustomErrorPage: boolean =
mappedPages['/_error'].startsWith('private-next-pages')
const hasPages404 = Boolean(
mappedPages['/404'] &&
mappedPages['/404'].startsWith('private-next-pages')
)
const hasPages404 = mappedPages['/404']?.startsWith(PAGES_DIR_ALIAS)
const hasCustomErrorPage =
mappedPages['/_error'].startsWith(PAGES_DIR_ALIAS)

if (hasMiddleware) {
if (pageKeys.some((page) => MIDDLEWARE_ROUTE.test(page))) {
Log.warn(
`using beta Middleware (not covered by semver) - https://nextjs.org/docs/messages/beta-middleware`
)
Expand Down Expand Up @@ -560,11 +565,8 @@ export default async function build(
)
)

const manifestPath = path.join(
distDir,
isLikeServerless ? SERVERLESS_DIRECTORY : SERVER_DIRECTORY,
PAGES_MANIFEST
)
const serverDir = isLikeServerless ? SERVERLESS_DIRECTORY : SERVER_DIRECTORY
const manifestPath = path.join(distDir, serverDir, PAGES_MANIFEST)

const requiredServerFiles = nextBuildSpan
.traceChild('generate-required-server-files')
Expand Down Expand Up @@ -595,12 +597,7 @@ export default async function build(
]
: []),
REACT_LOADABLE_MANIFEST,
config.optimizeFonts
? path.join(
isLikeServerless ? SERVERLESS_DIRECTORY : SERVER_DIRECTORY,
FONT_MANIFEST
)
: null,
config.optimizeFonts ? path.join(serverDir, FONT_MANIFEST) : null,
BUILD_ID_FILE,
]
.filter(nonNullable)
Expand All @@ -614,49 +611,37 @@ export default async function build(
await (async () => {
// IIFE to isolate locals and avoid retaining memory too long
const runWebpackSpan = nextBuildSpan.traceChild('run-webpack-compiler')

const commonWebpackOptions = {
buildId,
config,
hasReactRoot,
pagesDir,
reactProductionProfiling,
rewrites,
runWebpackSpan,
target,
}

const configs = await runWebpackSpan
.traceChild('generate-webpack-config')
.traceAsyncFn(() =>
Promise.all([
getBaseWebpackConfig(dir, {
buildId,
reactProductionProfiling,
isServer: false,
config,
target,
pagesDir,
...commonWebpackOptions,
compilerType: 'client',
entrypoints: entrypoints.client,
rewrites,
runWebpackSpan,
hasReactRoot,
}),
getBaseWebpackConfig(dir, {
buildId,
reactProductionProfiling,
isServer: true,
config,
target,
pagesDir,
...commonWebpackOptions,
compilerType: 'server',
entrypoints: entrypoints.server,
rewrites,
runWebpackSpan,
hasReactRoot,
}),
hasReactRoot
? getBaseWebpackConfig(dir, {
buildId,
reactProductionProfiling,
isServer: true,
isEdgeRuntime: true,
config,
target,
pagesDir,
entrypoints: entrypoints.edgeServer,
rewrites,
runWebpackSpan,
hasReactRoot,
})
: null,
getBaseWebpackConfig(dir, {
...commonWebpackOptions,
compilerType: 'edge-server',
entrypoints: entrypoints.edgeServer,
}),
])
)

Expand Down Expand Up @@ -1464,7 +1449,7 @@ export default async function build(

const middlewareManifest: MiddlewareManifest = JSON.parse(
await promises.readFile(
path.join(distDir, SERVER_DIRECTORY, MIDDLEWARE_MANIFEST),
path.join(distDir, serverDir, MIDDLEWARE_MANIFEST),
'utf8'
)
)
Expand Down Expand Up @@ -1651,10 +1636,6 @@ export default async function build(
const serverBundle = getPagePath(page, distDir, isLikeServerless)
await promises.unlink(serverBundle)
}
const serverOutputDir = path.join(
distDir,
isLikeServerless ? SERVERLESS_DIRECTORY : SERVER_DIRECTORY
)

const moveExportedPage = async (
originPage: string,
Expand All @@ -1677,7 +1658,7 @@ export default async function build(

const relativeDest = path
.relative(
serverOutputDir,
path.join(distDir, serverDir),
path.join(
path.join(
pagePath,
Expand All @@ -1694,12 +1675,6 @@ export default async function build(
)
.replace(/\\/g, '/')

const dest = path.join(
distDir,
isLikeServerless ? SERVERLESS_DIRECTORY : SERVER_DIRECTORY,
relativeDest
)

if (
!isSsg &&
!(
Expand All @@ -1714,6 +1689,7 @@ export default async function build(
pagesManifest[page] = relativeDest
}

const dest = path.join(distDir, serverDir, relativeDest)
const isNotFound = ssgNotFoundPaths.includes(page)

// for SSG files with i18n the non-prerendered variants are
Expand Down Expand Up @@ -1759,7 +1735,7 @@ export default async function build(
)
const updatedDest = path.join(
distDir,
isLikeServerless ? SERVERLESS_DIRECTORY : SERVER_DIRECTORY,
serverDir,
updatedRelativeDest
)

Expand Down
20 changes: 7 additions & 13 deletions packages/next/build/utils.ts
Expand Up @@ -21,7 +21,6 @@ import {
MIDDLEWARE_ROUTE,
} from '../lib/constants'
import prettyBytes from '../lib/pretty-bytes'
import { recursiveReadDir } from '../lib/recursive-readdir'
import { getRouteMatcher, getRouteRegex } from '../shared/lib/router/utils'
import { isDynamicRoute } from '../shared/lib/router/utils/is-dynamic'
import escapePathDelimiters from '../shared/lib/router/utils/escape-path-delimiters'
Expand Down Expand Up @@ -62,16 +61,6 @@ const fsStat = (file: string) => {
return (fileStats[file] = fileSize(file))
}

export function collectPages(
directory: string,
pageExtensions: string[]
): Promise<string[]> {
return recursiveReadDir(
directory,
new RegExp(`\\.(?:${pageExtensions.join('|')})$`)
)
}

export interface PageInfo {
isHybridAmp?: boolean
size: number
Expand Down Expand Up @@ -1103,7 +1092,12 @@ export function detectConflictingPaths(
}
}

export function getRawPageExtensions(pageExtensions: string[]): string[] {
/**
* With RSC we automatically add .server and .client to page extensions. This
* function allows to remove them for cases where we just need to strip out
* the actual extension keeping the .server and .client.
*/
export function withoutRSCExtensions(pageExtensions: string[]): string[] {
return pageExtensions.filter(
(ext) => !ext.startsWith('client.') && !ext.startsWith('server.')
)
Expand All @@ -1117,7 +1111,7 @@ export function isFlightPage(
return false
}

const rawPageExtensions = getRawPageExtensions(
const rawPageExtensions = withoutRSCExtensions(
nextConfig.pageExtensions || []
)
return rawPageExtensions.some((ext) => {
Expand Down