Skip to content

Commit 2335377

Browse files
authored
Fix next-server trace including dev server dependencies (#45359)
This ensures we aren't including the `dev-server` dependencies in the `next-server` tracing. x-ref: https://dev.azure.com/nextjs/next.js/_build/results?buildId=46884&view=logs&jobId=14d0eb3f-bc66-5450-3353-28256327ad6c x-ref: https://dev.azure.com/nextjs/next.js/_build/results?buildId=46889&view=logs&jobId=14d0eb3f-bc66-5450-3353-28256327ad6c
1 parent 1404eed commit 2335377

File tree

6 files changed

+115
-133
lines changed

6 files changed

+115
-133
lines changed

packages/next/src/build/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1950,6 +1950,7 @@ export default async function build(
19501950
'**/next/dist/compiled/webpack/(bundle4|bundle5).js',
19511951
'**/node_modules/webpack5/**/*',
19521952
'**/next/dist/server/lib/squoosh/**/*.wasm',
1953+
'**/next/dist/server/lib/route-resolver*',
19531954
...(ciEnvironment.hasNextSupport
19541955
? [
19551956
// only ignore image-optimizer code when
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import type { IncomingMessage, ServerResponse } from 'http'
2+
import type { UnwrapPromise } from '../../lib/coalesced-function'
3+
import type { NextConfig } from '../config'
4+
import type { Route } from '../router'
5+
6+
export async function makeResolver(dir: string, nextConfig: NextConfig) {
7+
const url = require('url') as typeof import('url')
8+
const { default: Router } = require('../router') as typeof import('../router')
9+
const { getPathMatch } =
10+
require('../../shared/lib/router/utils/path-match') as typeof import('../../shared/lib/router/utils/path-match')
11+
const { default: DevServer } =
12+
require('../dev/next-dev-server') as typeof import('../dev/next-dev-server')
13+
14+
const { NodeNextRequest, NodeNextResponse } =
15+
require('../base-http/node') as typeof import('../base-http/node')
16+
17+
const { default: loadCustomRoutes } =
18+
require('../../lib/load-custom-routes') as typeof import('../../lib/load-custom-routes')
19+
20+
const devServer = new DevServer({
21+
dir,
22+
conf: nextConfig,
23+
}) as any as {
24+
customRoutes: UnwrapPromise<ReturnType<typeof loadCustomRoutes>>
25+
router: InstanceType<typeof Router>
26+
generateRoutes: any
27+
}
28+
devServer.customRoutes = await loadCustomRoutes(nextConfig)
29+
const routes = devServer.generateRoutes.bind(devServer)()
30+
devServer.router = new Router(routes)
31+
const routeResults = new Map<string, string>()
32+
33+
// @ts-expect-error internal field
34+
devServer.router.catchAllRoute = {
35+
match: getPathMatch('/:path*'),
36+
name: 'catchall route',
37+
fn: async (req, _res, _params, parsedUrl) => {
38+
// clean up internal query values
39+
for (const key of Object.keys(parsedUrl.query || {})) {
40+
if (key.startsWith('_next')) {
41+
delete parsedUrl.query[key]
42+
}
43+
}
44+
45+
routeResults.set(
46+
(req as any)._initUrl,
47+
url.format({
48+
pathname: parsedUrl.pathname,
49+
query: parsedUrl.query,
50+
hash: parsedUrl.hash,
51+
})
52+
)
53+
return { finished: true }
54+
},
55+
} as Route
56+
57+
// @ts-expect-error internal field
58+
devServer.router.compiledRoutes = devServer.router.compiledRoutes.filter(
59+
(route: Route) => {
60+
return (
61+
route.type === 'rewrite' ||
62+
route.type === 'redirect' ||
63+
route.type === 'header' ||
64+
route.name === 'catchall route' ||
65+
route.name?.includes('check')
66+
)
67+
}
68+
)
69+
70+
return async function resolveRoute(
71+
_req: IncomingMessage,
72+
_res: ServerResponse
73+
) {
74+
const req = new NodeNextRequest(_req)
75+
const res = new NodeNextResponse(_res)
76+
;(req as any)._initUrl = req.url
77+
78+
await devServer.router.execute.bind(devServer.router)(
79+
req,
80+
res,
81+
url.parse(req.url!, true)
82+
)
83+
84+
if (!res.originalResponse.headersSent) {
85+
res.setHeader('x-nextjs-route-result', '1')
86+
const resolvedUrl = routeResults.get((req as any)._initUrl) || req.url!
87+
const routeResult: {
88+
url: string
89+
statusCode: number
90+
headers: Record<string, undefined | number | string | string[]>
91+
isRedirect?: boolean
92+
} = {
93+
url: resolvedUrl,
94+
statusCode: 200,
95+
headers: {},
96+
}
97+
98+
res.body(JSON.stringify(routeResult)).send()
99+
}
100+
}
101+
}

packages/next/src/server/router.ts

Lines changed: 7 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ import { removePathPrefix } from '../shared/lib/router/utils/remove-path-prefix'
2121
import { getRequestMeta } from './request-meta'
2222
import { formatNextPathnameInfo } from '../shared/lib/router/utils/format-next-pathname-info'
2323
import { getNextPathnameInfo } from '../shared/lib/router/utils/get-next-pathname-info'
24-
import type { IncomingMessage, ServerResponse } from 'http'
25-
import type { UnwrapPromise } from '../lib/coalesced-function'
2624

2725
type RouteResult = {
2826
finished: boolean
@@ -506,105 +504,13 @@ export default class Router {
506504

507505
let _makeResolver: any = () => {}
508506

509-
if (process.env.NEXT_RUNTIME !== 'edge') {
510-
_makeResolver = async function makeResolver(
511-
dir: string,
512-
nextConfig: NextConfig
513-
) {
514-
// TODO: why are there double defaults here?
515-
const { default: DevServer } =
516-
require('./dev/next-dev-server.js') as typeof import('./dev/next-dev-server')
517-
518-
const { default: loadCustomRoutes } =
519-
require('../lib/load-custom-routes') as typeof import('../lib/load-custom-routes')
520-
521-
const { NodeNextRequest, NodeNextResponse } =
522-
require('./base-http/node') as typeof import('./base-http/node')
523-
524-
const url = require('url') as typeof import('url')
525-
526-
const devServer = new DevServer({
527-
dir,
528-
conf: nextConfig,
529-
}) as any as {
530-
customRoutes: UnwrapPromise<ReturnType<typeof loadCustomRoutes>>
531-
router: Router
532-
generateRoutes: any
533-
}
534-
devServer.customRoutes = await loadCustomRoutes(nextConfig)
535-
const routes = devServer.generateRoutes.bind(devServer)()
536-
devServer.router = new Router(routes)
537-
const routeResults = new Map<string, string>()
538-
539-
// @ts-expect-error internal field
540-
devServer.router.catchAllRoute = {
541-
match: getPathMatch('/:path*'),
542-
name: 'catchall route',
543-
fn: async (req, _res, _params, parsedUrl) => {
544-
// clean up internal query values
545-
for (const key of Object.keys(parsedUrl.query || {})) {
546-
if (key.startsWith('_next')) {
547-
delete parsedUrl.query[key]
548-
}
549-
}
550-
551-
routeResults.set(
552-
(req as any)._initUrl,
553-
url.format({
554-
pathname: parsedUrl.pathname,
555-
query: parsedUrl.query,
556-
hash: parsedUrl.hash,
557-
})
558-
)
559-
return { finished: true }
560-
},
561-
} as Route
562-
563-
// @ts-expect-error internal field
564-
devServer.router.compiledRoutes = devServer.router.compiledRoutes.filter(
565-
(route) => {
566-
return (
567-
route.type === 'rewrite' ||
568-
route.type === 'redirect' ||
569-
route.type === 'header' ||
570-
route.name === 'catchall route' ||
571-
route.name?.includes('check')
572-
)
573-
}
574-
)
575-
576-
return async function resolveRoute(
577-
_req: IncomingMessage,
578-
_res: ServerResponse
579-
) {
580-
const req = new NodeNextRequest(_req)
581-
const res = new NodeNextResponse(_res)
582-
;(req as any)._initUrl = req.url
583-
584-
await devServer.router.execute.bind(devServer.router)(
585-
req,
586-
res,
587-
url.parse(req.url!, true)
588-
)
589-
590-
if (!res.originalResponse.headersSent) {
591-
res.setHeader('x-nextjs-route-result', '1')
592-
const resolvedUrl = routeResults.get((req as any)._initUrl) || req.url!
593-
const routeResult: {
594-
url: string
595-
statusCode: number
596-
headers: Record<string, undefined | number | string | string[]>
597-
isRedirect?: boolean
598-
} = {
599-
url: resolvedUrl,
600-
statusCode: 200,
601-
headers: {},
602-
}
603-
604-
res.body(JSON.stringify(routeResult)).send()
605-
}
606-
}
607-
}
507+
if (
508+
// ensure this isn't bundled for edge runtime
509+
process.env.NEXT_RUNTIME !== 'edge' &&
510+
// only load if we are inside of the turbopack handler
511+
process.argv.some((arg) => arg.endsWith('router.js'))
512+
) {
513+
_makeResolver = require('./lib/route-resolver').makeResolver
608514
}
609515

610516
export const makeResolver = _makeResolver

packages/next/taskfile.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export async function ncc_next_server(task, opts) {
100100
externals: {
101101
...externals,
102102

103-
'/(.*)next-dev-server(.*)/': '$1next-dev-server$1',
103+
'/(.*)route-resolver/': '$1route-resolver',
104104

105105
sharp: 'sharp',
106106
react: 'react',

test/integration/custom-routes/test/index.test.js

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2404,37 +2404,6 @@ describe('Custom routes', () => {
24042404
runTests(true)
24052405
})
24062406

2407-
describe('dev mode turbo', () => {
2408-
let nextConfigContent
2409-
2410-
beforeAll(async () => {
2411-
// ensure cache with rewrites disabled doesn't persist
2412-
// after enabling rewrites
2413-
await fs.remove(join(appDir, '.next'))
2414-
nextConfigContent = await fs.readFile(nextConfigPath, 'utf8')
2415-
await fs.writeFile(
2416-
nextConfigPath,
2417-
nextConfigContent.replace('// no-rewrites comment', 'return []')
2418-
)
2419-
2420-
const tempPort = await findPort()
2421-
const tempApp = await launchApp(appDir, tempPort, { turbo: true })
2422-
await renderViaHTTP(tempPort, '/')
2423-
2424-
await killApp(tempApp)
2425-
await fs.writeFile(nextConfigPath, nextConfigContent)
2426-
2427-
appPort = await findPort()
2428-
app = await launchApp(appDir, appPort)
2429-
buildId = 'development'
2430-
})
2431-
afterAll(async () => {
2432-
await fs.writeFile(nextConfigPath, nextConfigContent)
2433-
await killApp(app)
2434-
})
2435-
runTests(true)
2436-
})
2437-
24382407
describe('no-op rewrite', () => {
24392408
beforeAll(async () => {
24402409
appPort = await findPort()

test/integration/production/test/index.test.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,11 @@ describe('Production Usage', () => {
163163
file.includes('next/dist/server/send-payload/index.js')
164164
)
165165
).toBe(true)
166+
expect(
167+
serverTrace.files.some((file) =>
168+
file.includes('next/dist/server/lib/route-resolver.js')
169+
)
170+
).toBe(false)
166171
const repoRoot = join(__dirname, '../../../../')
167172
expect(
168173
serverTrace.files.some((file) => {

0 commit comments

Comments
 (0)