Skip to content

Commit

Permalink
[turbopack]: Serve _devMiddlewareManifest.json from router (#50241)
Browse files Browse the repository at this point in the history
This change allows the Turbopack's node router to serve
`_next/static/development/_devMiddlewareManifest.json` file, which is
just the matchers for middleware routes. This is usually handled by the
node dev server anyways, but we were filtering out the route so that
Turbopack could handle it.

But, Turbopack doesn't implement the route matching logic at all, it's
all handled by our node router. So Turbopack can't know what the
middleware matchers are. Having the router just handle this like the
normal dev server is both easy and efficient (I don't want to spin up
_another_ node instance just to transform the matchers into the expected
format).

Fixes WEB-979

---------

Co-authored-by: JJ Kasper <jj@jjsweb.site>
  • Loading branch information
jridgewell and ijjk committed May 25, 2023
1 parent 1079c10 commit 12e22ed
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 25 deletions.
12 changes: 6 additions & 6 deletions packages/next-swc/crates/next-core/js/src/entry/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ import 'next/dist/server/node-polyfill-fetch.js'
import middlewareChunkGroup from 'MIDDLEWARE_CHUNK_GROUP'
import middlewareConfig from 'MIDDLEWARE_CONFIG'

type Resolver = Awaited<
ReturnType<typeof import('next/dist/server/lib/route-resolver').makeResolver>
>

type RouterRequest = {
method: string
pathname: string
Expand Down Expand Up @@ -51,16 +55,12 @@ type MiddlewareHeadersResponse = {
headers: [string, string][]
}

let resolveRouteMemo: Promise<
(req: IncomingMessage, res: ServerResponse) => Promise<void>
>
let resolveRouteMemo: Promise<Resolver>

async function getResolveRoute(
dir: string,
serverInfo: ServerInfo
): ReturnType<
typeof import('next/dist/server/lib/route-resolver').makeResolver
> {
): Promise<Resolver> {
const nextConfig = await loadConfig(
PHASE_DEVELOPMENT_SERVER,
process.cwd(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,3 @@ globalThis.__webpack_require__ = (name) => {

// initialize() needs `__webpack_public_path__` to be defined.
globalThis.__webpack_public_path__ = undefined

// Avoids Next loading _next/static/[buildId]/_devMiddlewareManifest.json
globalThis.__DEV_MIDDLEWARE_MATCHERS = []
6 changes: 5 additions & 1 deletion packages/next-swc/crates/next-core/src/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,11 @@ impl ContentSource for DevManifestContentSource {
File::from(build_manifest.as_str()).with_content_type(APPLICATION_JAVASCRIPT_UTF_8)
}
"_next/static/development/_devMiddlewareManifest.json" => {
// empty middleware manifest
// If there is actual middleware, this request will have been handled by the
// node router in next-core/js/src/entry/router.ts and
// next/src/server/lib/route-resolver.ts.
// If we've reached this point, then there is no middleware and we need to
// respond with an empty `MiddlewareMatcher[]`.
File::from("[]").with_content_type(APPLICATION_JSON)
}
_ => return Ok(ContentSourceResultVc::not_found()),
Expand Down
18 changes: 3 additions & 15 deletions packages/next/src/server/lib/route-resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { getMiddlewareMatchers } from '../../build/analysis/get-page-static-info
import { getMiddlewareRouteMatcher } from '../../shared/lib/router/utils/middleware-route-matcher'
import {
CLIENT_STATIC_FILES_PATH,
DEV_CLIENT_PAGES_MANIFEST,
DEV_MIDDLEWARE_MANIFEST,
} from '../../shared/lib/constants'
import type { BaseNextRequest } from '../base-http'

Expand Down Expand Up @@ -193,20 +193,6 @@ export async function makeResolver(
// @ts-expect-error protected
const buildId = devServer.buildId

const pagesManifestRoute = routes.fsRoutes.find(
(r) =>
r.name ===
`_next/${CLIENT_STATIC_FILES_PATH}/${buildId}/${DEV_CLIENT_PAGES_MANIFEST}`
)
if (pagesManifestRoute) {
// make sure turbopack serves this
pagesManifestRoute.fn = () => {
return {
finished: true,
}
}
}

const router = new Router({
...routes,
catchAllMiddleware,
Expand Down Expand Up @@ -245,6 +231,8 @@ export async function makeResolver(
route.type === 'header' ||
route.name === 'catchall route' ||
route.name === 'middleware catchall' ||
route.name ===
`_next/${CLIENT_STATIC_FILES_PATH}/${buildId}/${DEV_MIDDLEWARE_MANIFEST}` ||
route.name?.includes('check')
)
})
Expand Down

0 comments on commit 12e22ed

Please sign in to comment.