Skip to content

Commit

Permalink
add NEXT_TRIGGER_URL env var to show request triggering a compilati…
Browse files Browse the repository at this point in the history
…on (vercel#58762)

### What?

Shows the actual request url that triggered a compilation in the console
message

### Why?

makes it easier to find accidental compilation

### How?



Closes PACK-2017
  • Loading branch information
sokra committed Nov 27, 2023
1 parent 7874ad2 commit 4d330a8
Show file tree
Hide file tree
Showing 13 changed files with 110 additions and 30 deletions.
11 changes: 9 additions & 2 deletions packages/next/src/build/output/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type BuildStatusStore = {
server: WebpackStatus
edgeServer: WebpackStatus
trigger: string | undefined
url: string | undefined
amp: AmpPageStatus
}

Expand Down Expand Up @@ -111,7 +112,7 @@ let serverWasLoading = true
let edgeServerWasLoading = false

buildStore.subscribe((state) => {
const { amp, client, server, edgeServer, trigger } = state
const { amp, client, server, edgeServer, trigger, url } = state

const { appUrl } = consoleStore.getState()

Expand All @@ -123,6 +124,7 @@ buildStore.subscribe((state) => {
// If it takes more than 3 seconds to compile, mark it as loading status
loading: true,
trigger,
url,
} as OutputState,
true
)
Expand Down Expand Up @@ -230,6 +232,7 @@ export function watchCompilers(
server: { loading: true },
edgeServer: { loading: true },
trigger: 'initial',
url: undefined,
})

function tapCompiler(
Expand Down Expand Up @@ -273,6 +276,7 @@ export function watchCompilers(
buildStore.setState({
client: status,
trigger: undefined,
url: undefined,
})
} else {
buildStore.setState({
Expand All @@ -290,6 +294,7 @@ export function watchCompilers(
buildStore.setState({
server: status,
trigger: undefined,
url: undefined,
})
} else {
buildStore.setState({
Expand All @@ -307,6 +312,7 @@ export function watchCompilers(
buildStore.setState({
edgeServer: status,
trigger: undefined,
url: undefined,
})
} else {
buildStore.setState({
Expand All @@ -317,7 +323,7 @@ export function watchCompilers(
}

const internalSegments = ['[[...__metadata_id__]]', '[__metadata_id__]']
export function reportTrigger(trigger: string) {
export function reportTrigger(trigger: string, url?: string) {
for (const segment of internalSegments) {
if (trigger.includes(segment)) {
trigger = trigger.replace(segment, '')
Expand All @@ -330,5 +336,6 @@ export function reportTrigger(trigger: string) {

buildStore.setState({
trigger,
url,
})
}
13 changes: 12 additions & 1 deletion packages/next/src/build/output/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export type OutputState =
| {
loading: true
trigger: string | undefined
url: string | undefined
}
| {
loading: false
Expand Down Expand Up @@ -51,6 +52,7 @@ function hasStoreChanged(nextStore: OutputState) {

let startTime = 0
let trigger = '' // default, use empty string for trigger
let triggerUrl: string | undefined = undefined
let loadingLogTimer: NodeJS.Timeout | null = null
let traceSpan: Span | null = null

Expand All @@ -66,14 +68,23 @@ store.subscribe((state) => {
if (state.loading) {
if (state.trigger) {
trigger = state.trigger
triggerUrl = state.url
if (trigger !== 'initial') {
traceSpan = trace('compile-path', undefined, {
trigger: trigger,
})
if (!loadingLogTimer) {
// Only log compiling if compiled is not finished in 3 seconds
loadingLogTimer = setTimeout(() => {
Log.wait(`Compiling ${trigger} ...`)
if (
triggerUrl &&
triggerUrl !== trigger &&
process.env.NEXT_TRIGGER_URL
) {
Log.wait(`Compiling ${trigger} (${triggerUrl}) ...`)
} else {
Log.wait(`Compiling ${trigger} ...`)
}
}, MAX_LOG_SKIP_DURATION)
}
}
Expand Down
13 changes: 11 additions & 2 deletions packages/next/src/server/base-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
sriEnabled?: boolean
appPaths?: ReadonlyArray<string> | null
shouldEnsure?: boolean
url?: string
}): Promise<FindComponentsResult | null>
protected abstract getFontManifest(): FontManifest | undefined
protected abstract getPrerenderManifest(): PrerenderManifest
Expand Down Expand Up @@ -3006,7 +3007,9 @@ export default abstract class Server<ServerOptions extends Options = Options> {
}

protected abstract getMiddleware(): MiddlewareRoutingItem | undefined
protected abstract getFallbackErrorComponents(): Promise<LoadComponentsReturnType | null>
protected abstract getFallbackErrorComponents(
url?: string
): Promise<LoadComponentsReturnType | null>
protected abstract getRoutesManifest(): NormalizedRouteManifest | undefined

private async renderToResponseImpl(
Expand Down Expand Up @@ -3249,6 +3252,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
params: {},
isAppPath: true,
shouldEnsure: true,
url: ctx.req.url,
})
using404Page = result !== null
}
Expand All @@ -3261,6 +3265,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
isAppPath: false,
// Ensuring can't be done here because you never "match" a 404 route.
shouldEnsure: true,
url: ctx.req.url,
})
using404Page = result !== null
}
Expand All @@ -3283,6 +3288,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
// Ensuring can't be done here because you never "match" a 500
// route.
shouldEnsure: true,
url: ctx.req.url,
})
}
}
Expand All @@ -3296,6 +3302,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
// Ensuring can't be done here because you never "match" an error
// route.
shouldEnsure: true,
url: ctx.req.url,
})
statusPage = '/_error'
}
Expand Down Expand Up @@ -3376,7 +3383,9 @@ export default abstract class Server<ServerOptions extends Options = Options> {
this.logError(renderToHtmlError)
}
res.statusCode = 500
const fallbackComponents = await this.getFallbackErrorComponents()
const fallbackComponents = await this.getFallbackErrorComponents(
ctx.req.url
)

if (fallbackComponents) {
// There was an error, so use it's definition from the route module
Expand Down
2 changes: 2 additions & 0 deletions packages/next/src/server/dev/hot-reloader-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,13 @@ export interface NextJsHotReloaderInterface {
appPaths,
definition,
isApp,
url,
}: {
page: string
clientOnly: boolean
appPaths?: ReadonlyArray<string> | null
isApp?: boolean
definition: RouteDefinition | undefined
url?: string
}): Promise<void>
}
5 changes: 4 additions & 1 deletion packages/next/src/server/dev/hot-reloader-webpack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ export default class HotReloader implements NextJsHotReloaderInterface {

if (page === '/_error' || BLOCKED_PAGES.indexOf(page) === -1) {
try {
await this.ensurePage({ page, clientOnly: true })
await this.ensurePage({ page, clientOnly: true, url: req.url })
} catch (error) {
return await renderScriptError(pageBundleRes, getProperError(error))
}
Expand Down Expand Up @@ -1471,12 +1471,14 @@ export default class HotReloader implements NextJsHotReloaderInterface {
appPaths,
definition,
isApp,
url,
}: {
page: string
clientOnly: boolean
appPaths?: ReadonlyArray<string> | null
isApp?: boolean
definition?: RouteDefinition
url?: string
}): Promise<void> {
// Make sure we don't re-build or dispose prebuilt pages
if (page !== '/_error' && BLOCKED_PAGES.indexOf(page) !== -1) {
Expand All @@ -1494,6 +1496,7 @@ export default class HotReloader implements NextJsHotReloaderInterface {
appPaths,
definition,
isApp,
url,
})
}
}
20 changes: 16 additions & 4 deletions packages/next/src/server/dev/next-dev-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,11 +198,12 @@ export default class DevServer extends Server {
const { pagesDir, appDir } = findPagesDir(this.dir)

const ensurer: RouteEnsurer = {
ensure: async (match) => {
ensure: async (match, pathname) => {
await this.ensurePage({
definition: match.definition,
page: match.definition.page,
clientOnly: false,
url: pathname,
})
},
}
Expand Down Expand Up @@ -559,11 +560,12 @@ export default class DevServer extends Server {
return this.hasPage(this.actualMiddlewareFile!)
}

protected async ensureMiddleware() {
protected async ensureMiddleware(url: string) {
return this.ensurePage({
page: this.actualMiddlewareFile!,
clientOnly: false,
definition: undefined,
url,
})
}

Expand Down Expand Up @@ -597,15 +599,18 @@ export default class DevServer extends Server {
protected async ensureEdgeFunction({
page,
appPaths,
url,
}: {
page: string
appPaths: string[] | null
url: string
}) {
return this.ensurePage({
page,
appPaths,
clientOnly: false,
definition: undefined,
url,
})
}

Expand Down Expand Up @@ -762,6 +767,7 @@ export default class DevServer extends Server {
clientOnly: boolean
appPaths?: ReadonlyArray<string> | null
definition: RouteDefinition | undefined
url?: string
}): Promise<void> {
await this.bundlerService.ensurePage(opts)
}
Expand All @@ -773,6 +779,7 @@ export default class DevServer extends Server {
isAppPath,
appPaths = null,
shouldEnsure,
url,
}: {
page: string
query: NextParsedUrlQuery
Expand All @@ -781,6 +788,7 @@ export default class DevServer extends Server {
sriEnabled?: boolean
appPaths?: ReadonlyArray<string> | null
shouldEnsure: boolean
url?: string
}): Promise<FindComponentsResult | null> {
await this.ready?.promise

Expand All @@ -796,6 +804,7 @@ export default class DevServer extends Server {
appPaths,
clientOnly: false,
definition: undefined,
url,
})
}

Expand All @@ -812,6 +821,7 @@ export default class DevServer extends Server {
params,
isAppPath,
shouldEnsure,
url,
})
} catch (err) {
if ((err as any).code !== 'ENOENT') {
Expand All @@ -821,8 +831,10 @@ export default class DevServer extends Server {
}
}

protected async getFallbackErrorComponents(): Promise<LoadComponentsReturnType | null> {
await this.bundlerService.getFallbackErrorComponents()
protected async getFallbackErrorComponents(
url?: string
): Promise<LoadComponentsReturnType | null> {
await this.bundlerService.getFallbackErrorComponents(url)
return await loadDefaultErrorComponents(this.distDir)
}

Expand Down
7 changes: 6 additions & 1 deletion packages/next/src/server/dev/on-demand-entry-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -678,11 +678,13 @@ export function onDemandEntryHandler({
appPaths,
definition,
isApp,
url,
}: {
page: string
appPaths: ReadonlyArray<string> | null
definition: RouteDefinition | undefined
isApp: boolean | undefined
url?: string
}): Promise<void> {
const stalledTime = 60
const stalledEnsureTimeout = setTimeout(() => {
Expand Down Expand Up @@ -834,7 +836,7 @@ export function onDemandEntryHandler({

if (hasNewEntry) {
const routePage = isApp ? route.page : normalizeAppPath(route.page)
reportTrigger(routePage)
reportTrigger(routePage, url)
}

if (entriesThatShouldBeInvalidated.length > 0) {
Expand Down Expand Up @@ -877,6 +879,7 @@ export function onDemandEntryHandler({
appPaths?: ReadonlyArray<string> | null
definition?: RouteDefinition
isApp?: boolean
url?: string
}

// Make sure that we won't have multiple invalidations ongoing concurrently.
Expand All @@ -900,6 +903,7 @@ export function onDemandEntryHandler({
appPaths = null,
definition,
isApp,
url,
}: EnsurePageOptions) {
// If the route is actually an app page route, then we should have access
// to the app route definition, and therefore, the appPaths from it.
Expand All @@ -916,6 +920,7 @@ export function onDemandEntryHandler({
appPaths,
definition,
isApp,
url,
})
})
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { cyan } from '../../../lib/picocolors'
import type { RouteMatcher } from '../route-matchers/route-matcher'

export interface RouteEnsurer {
ensure(match: RouteMatch): Promise<void>
ensure(match: RouteMatch, pathname: string): Promise<void>
}

export class DevRouteMatcherManager extends DefaultRouteMatcherManager {
Expand Down Expand Up @@ -74,7 +74,7 @@ export class DevRouteMatcherManager extends DefaultRouteMatcherManager {
for await (const development of super.matchAll(pathname, options)) {
// We're here, which means that we haven't seen this match yet, so we
// should try to ensure it and recompile the production matcher.
await this.ensurer.ensure(development)
await this.ensurer.ensure(development, pathname)
await this.production.reload()

// Iterate over the production matches again, this time we should be able
Expand Down

0 comments on commit 4d330a8

Please sign in to comment.