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

refactor: simplify middleware execution #39192

Merged
merged 3 commits into from Jul 30, 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
1 change: 0 additions & 1 deletion packages/next/server/base-server.ts
Expand Up @@ -87,7 +87,6 @@ export type FindComponentsResult = {
export interface RoutingItem {
page: string
match: RouteMatch
ssr?: boolean
re?: RegExp
}

Expand Down
23 changes: 9 additions & 14 deletions packages/next/server/dev/next-dev-server.ts
Expand Up @@ -387,7 +387,6 @@ export default class DevServer extends Server {
match: getRouteMatcher(middlewareRegex),
page,
re: middlewareRegex.re,
ssr: !isRootMiddleware,
}

if (isRootMiddleware) {
Expand Down Expand Up @@ -911,17 +910,16 @@ export default class DevServer extends Server {
return undefined
}

protected async hasMiddleware(
pathname: string,
isSSR?: boolean
): Promise<boolean> {
return this.hasPage(isSSR ? pathname : this.actualMiddlewareFile!)
protected async hasMiddleware(): Promise<boolean> {
return this.hasPage(this.actualMiddlewareFile!)
}

protected async ensureMiddleware(pathname: string, isSSR?: boolean) {
return this.hotReloader!.ensurePage(
isSSR ? pathname : this.actualMiddlewareFile!
)
protected async ensureMiddleware() {
return this.hotReloader!.ensurePage(this.actualMiddlewareFile!)
}

protected async ensureEdgeFunction(pathname: string) {
return this.hotReloader!.ensurePage(pathname)
}

generateRoutes() {
Expand Down Expand Up @@ -979,10 +977,7 @@ export default class DevServer extends Server {
res
.body(
JSON.stringify(
edgeRoutes.map((edgeRoute) => [
edgeRoute.re!.source,
!!edgeRoute.ssr,
])
edgeRoutes.map((edgeRoute) => [edgeRoute.re!.source])
)
)
.send()
Expand Down
118 changes: 57 additions & 61 deletions packages/next/server/next-server.ts
Expand Up @@ -1054,14 +1054,15 @@ export default class NextNodeServer extends BaseServer {
*/
protected getMiddleware(): RoutingItem | undefined {
const manifest = this.getMiddlewareManifest()
if (!manifest) {
const rootMiddleware = manifest?.middleware?.['/']
if (!rootMiddleware) {
return
}

return manifest.sortedMiddleware.map((page) => ({
match: getMiddlewareMatcher(manifest.middleware[page]),
page,
}))[0]
return {
match: getMiddlewareMatcher(rootMiddleware),
page: '/',
}
}

protected getEdgeFunctions(): RoutingItem[] {
Expand Down Expand Up @@ -1139,20 +1140,18 @@ export default class NextNodeServer extends BaseServer {
* server where we need to check the filesystem. Here we just check the
* middleware manifest.
*/
protected async hasMiddleware(
pathname: string,
_isSSR?: boolean
): Promise<boolean> {
protected async hasMiddleware(pathname: string): Promise<boolean> {
const info = this.getEdgeFunctionInfo({ page: pathname, middleware: true })
return Boolean(info && info.paths.length > 0)
}

/**
* A placeholder for a function to be defined in the development server.
* It will make sure that the middleware has been compiled so that we
* can run it.
* It will make sure that the root middleware or an edge function has been compiled
* so that we can run it.
*/
protected async ensureMiddleware(_pathname: string, _isSSR?: boolean) {}
protected async ensureMiddleware() {}
protected async ensureEdgeFunction(_pathname: string) {}

/**
* This method gets all middleware matchers and execute them when the request
Expand Down Expand Up @@ -1210,61 +1209,58 @@ export default class NextNodeServer extends BaseServer {
let result: FetchEventResult | null = null
const method = (params.request.method || 'GET').toUpperCase()

const edgeRoutesList = this.getEdgeRoutes()
for (const middleware of edgeRoutesList) {
if (middleware.match(normalizedPathname)) {
if (!(await this.hasMiddleware(middleware.page, middleware.ssr))) {
console.warn(`The Edge Function for ${middleware.page} was not found`)
continue
}
const middleware = this.getMiddleware()
if (!middleware) {
return { finished: false }
}
if (!(await this.hasMiddleware(middleware.page))) {
console.warn(`The Edge Function for ${middleware.page} was not found`)
return { finished: false }
}

await this.ensureMiddleware(middleware.page, middleware.ssr)
const middlewareInfo = this.getEdgeFunctionInfo({
page: middleware.page,
middleware: !middleware.ssr,
})
if (middleware && middleware.match(normalizedPathname)) {
await this.ensureMiddleware()
const middlewareInfo = this.getEdgeFunctionInfo({
page: middleware.page,
middleware: true,
})

if (!middlewareInfo) {
throw new MiddlewareNotFoundError()
}
if (!middlewareInfo) {
throw new MiddlewareNotFoundError()
}

result = await run({
distDir: this.distDir,
name: middlewareInfo.name,
paths: middlewareInfo.paths,
env: middlewareInfo.env,
edgeFunctionEntry: middlewareInfo,
request: {
headers: params.request.headers,
method,
nextConfig: {
basePath: this.nextConfig.basePath,
i18n: this.nextConfig.i18n,
trailingSlash: this.nextConfig.trailingSlash,
},
url: url,
page: page,
body: getRequestMeta(params.request, '__NEXT_CLONABLE_BODY'),
result = await run({
distDir: this.distDir,
name: middlewareInfo.name,
paths: middlewareInfo.paths,
env: middlewareInfo.env,
edgeFunctionEntry: middlewareInfo,
request: {
headers: params.request.headers,
method,
nextConfig: {
basePath: this.nextConfig.basePath,
i18n: this.nextConfig.i18n,
trailingSlash: this.nextConfig.trailingSlash,
},
useCache: !this.nextConfig.experimental.runtime,
onWarning: params.onWarning,
})

for (let [key, value] of result.response.headers) {
if (key !== 'x-middleware-next') {
allHeaders.append(key, value)
}
}
url: url,
page: page,
body: getRequestMeta(params.request, '__NEXT_CLONABLE_BODY'),
},
useCache: !this.nextConfig.experimental.runtime,
onWarning: params.onWarning,
})

if (!this.renderOpts.dev) {
result.waitUntil.catch((error) => {
console.error(`Uncaught: middleware waitUntil errored`, error)
})
for (let [key, value] of result.response.headers) {
if (key !== 'x-middleware-next') {
allHeaders.append(key, value)
}
}

if (!result.response.headers.has('x-middleware-next')) {
break
}
if (!this.renderOpts.dev) {
result.waitUntil.catch((error) => {
console.error(`Uncaught: middleware waitUntil errored`, error)
})
}
}

Expand Down Expand Up @@ -1554,7 +1550,7 @@ export default class NextNodeServer extends BaseServer {
let middlewareInfo: ReturnType<typeof this.getEdgeFunctionInfo> | undefined

try {
await this.ensureMiddleware(params.page, true)
await this.ensureEdgeFunction(params.page)
middlewareInfo = this.getEdgeFunctionInfo({
page: params.page,
middleware: false,
Expand Down