Fix: strip _rsc query for client navigation rsc request (#65084)
When you do client navigation to a dynamic page with call like `headers()`, it wil send RSC request for that page. We want to skip the `_rsc` query in the logging as it's disruptive. Closes NEXT-3077 Closes #64355
This commit is contained in:
parent
3f907d38cb
commit
b9c98a8866
7 changed files with 76 additions and 11 deletions
|
@ -1338,7 +1338,7 @@ function loadNative(importPath?: string) {
|
|||
try {
|
||||
// Use the binary directly to skip `pnpm pack` for testing as it's slow because of the large native binary.
|
||||
bindings = require(`${NEXT_TEST_NATIVE_DIR}/next-swc.${triple.platformArchABI}.node`)
|
||||
console.log(
|
||||
infoLog(
|
||||
'next-swc build: local built @next/swc from NEXT_TEST_NATIVE_DIR'
|
||||
)
|
||||
break
|
||||
|
@ -1346,7 +1346,7 @@ function loadNative(importPath?: string) {
|
|||
} else {
|
||||
try {
|
||||
bindings = require(`@next/swc/native/next-swc.${triple.platformArchABI}.node`)
|
||||
console.log('next-swc build: local built @next/swc')
|
||||
infoLog('next-swc build: local built @next/swc')
|
||||
break
|
||||
} catch (e) {}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
const DUMMY_ORIGIN = 'http://n'
|
||||
import { NEXT_RSC_UNION_QUERY } from '../client/components/app-router-headers'
|
||||
|
||||
export const DUMMY_ORIGIN = 'http://n'
|
||||
|
||||
function getUrlWithoutHost(url: string) {
|
||||
return new URL(url, DUMMY_ORIGIN)
|
||||
|
@ -11,3 +13,10 @@ export function getPathname(url: string) {
|
|||
export function isFullStringUrl(url: string) {
|
||||
return /https?:\/\//.test(url)
|
||||
}
|
||||
|
||||
export function stripNextRscUnionQuery(relativeUrl: string): string {
|
||||
const urlInstance = new URL(relativeUrl, DUMMY_ORIGIN)
|
||||
urlInstance.searchParams.delete(NEXT_RSC_UNION_QUERY)
|
||||
|
||||
return urlInstance.pathname + urlInstance.search
|
||||
}
|
||||
|
|
|
@ -104,6 +104,7 @@ import { interopDefault } from '../lib/interop-default'
|
|||
import { formatDynamicImportPath } from '../lib/format-dynamic-import-path'
|
||||
import type { NextFontManifest } from '../build/webpack/plugins/next-font-manifest-plugin'
|
||||
import { isInterceptionRouteRewrite } from '../lib/generate-interception-routes-rewrites'
|
||||
import { stripNextRscUnionQuery } from '../lib/url'
|
||||
|
||||
export * from './base-server'
|
||||
|
||||
|
@ -1123,9 +1124,9 @@ export default class NextNodeServer extends BaseServer<
|
|||
// we don't log for non-route requests
|
||||
const routeMatch = getRequestMeta(req).match
|
||||
|
||||
const isRSC = isRSCRequestCheck(normalizedReq)
|
||||
if (!routeMatch || isRSC || isMiddlewareRequest) return
|
||||
if (!routeMatch || isMiddlewareRequest) return
|
||||
|
||||
const isRSC = isRSCRequestCheck(normalizedReq)
|
||||
const reqEnd = Date.now()
|
||||
const fetchMetrics = normalizedReq.fetchMetrics || []
|
||||
const reqDuration = reqEnd - reqStart
|
||||
|
@ -1140,9 +1141,14 @@ export default class NextNodeServer extends BaseServer<
|
|||
|
||||
const color = statusColor(res.statusCode)
|
||||
const method = req.method || 'GET'
|
||||
const requestUrl = req.url || ''
|
||||
const loggingUrl = isRSC
|
||||
? stripNextRscUnionQuery(requestUrl)
|
||||
: requestUrl
|
||||
|
||||
writeStdoutLine(
|
||||
`${method} ${req.url ?? ''} ${color(
|
||||
(res.statusCode ?? 200).toString()
|
||||
`${method} ${loggingUrl} ${color(
|
||||
res.statusCode.toString()
|
||||
)} in ${reqDuration}ms`
|
||||
)
|
||||
|
||||
|
@ -1798,6 +1804,10 @@ export default class NextNodeServer extends BaseServer<
|
|||
? `https://${req.headers.host || 'localhost'}${req.url}`
|
||||
: req.url
|
||||
|
||||
const isRSC = isRSCRequestCheck(req)
|
||||
if (isRSC) {
|
||||
addRequestMeta(req, 'isRSCRequest', true)
|
||||
}
|
||||
addRequestMeta(req, 'initURL', initUrl)
|
||||
addRequestMeta(req, 'initQuery', { ...parsedUrl.query })
|
||||
addRequestMeta(req, 'initProtocol', protocol)
|
||||
|
|
6
test/e2e/app-dir/logging/app/headers/page.js
Normal file
6
test/e2e/app-dir/logging/app/headers/page.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
import { headers } from 'next/headers'
|
||||
|
||||
export default function Page() {
|
||||
headers()
|
||||
return <p>{'headers()'}</p>
|
||||
}
|
|
@ -1,7 +1,29 @@
|
|||
import Link from 'next/link'
|
||||
|
||||
export default function Layout({ children }) {
|
||||
return (
|
||||
<html>
|
||||
<body>{children}</body>
|
||||
<body>
|
||||
<header>
|
||||
<Link id="nav-link" href={'/link'}>
|
||||
/link
|
||||
</Link>
|
||||
<br />
|
||||
<Link id="nav-headers" href={'/headers'}>
|
||||
/headers
|
||||
</Link>
|
||||
<br />
|
||||
<Link id="nav-default-cache" href={'/default-cache'}>
|
||||
/default-cache
|
||||
</Link>
|
||||
<br />
|
||||
<Link id="nav-cache-revalidate" href={'/cache-revalidate'}>
|
||||
/cache-revalidate
|
||||
</Link>
|
||||
<br />
|
||||
</header>
|
||||
<div>{children}</div>
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
import Link from 'next/link'
|
||||
|
||||
export default function Page() {
|
||||
return <Link href="/foo">Trigger RSC request</Link>
|
||||
return (
|
||||
<Link id="foo" href="/foo">
|
||||
Trigger RSC request
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -167,16 +167,30 @@ describe('app-dir - logging', () => {
|
|||
})
|
||||
})
|
||||
|
||||
it('should exlucde Middleware invoked and _rsc requests', async () => {
|
||||
it('should exclude Middleware invoked and _rsc requests', async () => {
|
||||
const outputIndex = next.cliOutput.length
|
||||
|
||||
const browser = await next.browser('/link')
|
||||
await browser.elementByCss('a').click()
|
||||
await browser.elementByCss('a#foo').click()
|
||||
await browser.waitForElementByCss('h2')
|
||||
const logs = stripAnsi(next.cliOutput.slice(outputIndex))
|
||||
expect(logs).not.toContain('/_next/static')
|
||||
expect(logs).not.toContain('?_rsc')
|
||||
})
|
||||
|
||||
it('should not log _rsc query for client navigation RSC request', async () => {
|
||||
const outputIndex = next.cliOutput.length
|
||||
|
||||
const browser = await next.browser('/')
|
||||
await browser.elementByCss('a#nav-headers').click()
|
||||
await browser.waitForElementByCss('p')
|
||||
const logs = stripAnsi(next.cliOutput.slice(outputIndex))
|
||||
|
||||
expect(logs).toContain('GET /')
|
||||
expect(logs).toContain('GET /headers')
|
||||
expect(logs).not.toContain('/_next/static')
|
||||
expect(logs).not.toContain('?_rsc')
|
||||
})
|
||||
}
|
||||
} else {
|
||||
// No fetches logging enabled
|
||||
|
|
Loading…
Reference in a new issue