Skip to content

Commit 059c255

Browse files
authored
[dev-overlay] Always show relative paths (#76742)
1 parent 5d53fd0 commit 059c255

File tree

8 files changed

+147
-115
lines changed

8 files changed

+147
-115
lines changed

Diff for: packages/next/src/client/components/react-dev-overlay/server/middleware-turbopack.ts

+28-13
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ function shouldIgnorePath(modulePath: string): boolean {
3434
type IgnorableStackFrame = StackFrame & { ignored: boolean }
3535

3636
const currentSourcesByFile: Map<string, Promise<string | null>> = new Map()
37-
export async function batchedTraceSource(
37+
async function batchedTraceSource(
3838
project: Project,
3939
frame: TurbopackStackFrame
4040
): Promise<{ frame: IgnorableStackFrame; source: string | null } | undefined> {
@@ -316,9 +316,7 @@ async function nativeTraceSource(
316316
?.replace('__WEBPACK_DEFAULT_EXPORT__', 'default')
317317
?.replace('__webpack_exports__.', '') || '<unknown>',
318318
column: (originalPosition.column ?? 0) + 1,
319-
file: originalPosition.source?.startsWith('file://')
320-
? relativeToCwd(originalPosition.source)
321-
: originalPosition.source,
319+
file: originalPosition.source,
322320
lineNumber: originalPosition.line ?? 0,
323321
// TODO: c&p from async createOriginalStackFrame but why not frame.arguments?
324322
arguments: [],
@@ -335,14 +333,9 @@ async function nativeTraceSource(
335333
return undefined
336334
}
337335

338-
function relativeToCwd(file: string): string {
339-
const relPath = path.relative(process.cwd(), url.fileURLToPath(file))
340-
// TODO(sokra) include a ./ here to make it a relative path
341-
return relPath
342-
}
343-
344336
async function createOriginalStackFrame(
345337
project: Project,
338+
projectPath: string,
346339
frame: TurbopackStackFrame
347340
): Promise<OriginalStackFrameResponse | null> {
348341
const traced =
@@ -354,13 +347,31 @@ async function createOriginalStackFrame(
354347
return null
355348
}
356349

350+
let normalizedStackFrameLocation = traced.frame.file
351+
if (
352+
normalizedStackFrameLocation !== null &&
353+
normalizedStackFrameLocation.startsWith('file://')
354+
) {
355+
normalizedStackFrameLocation = path.relative(
356+
projectPath,
357+
url.fileURLToPath(normalizedStackFrameLocation)
358+
)
359+
}
360+
357361
return {
358-
originalStackFrame: traced.frame,
362+
originalStackFrame: {
363+
arguments: traced.frame.arguments,
364+
column: traced.frame.column,
365+
file: normalizedStackFrameLocation,
366+
ignored: traced.frame.ignored,
367+
lineNumber: traced.frame.lineNumber,
368+
methodName: traced.frame.methodName,
369+
},
359370
originalCodeFrame: getOriginalCodeFrame(traced.frame, traced.source),
360371
}
361372
}
362373

363-
export function getOverlayMiddleware(project: Project) {
374+
export function getOverlayMiddleware(project: Project, projectPath: string) {
364375
return async function (
365376
req: IncomingMessage,
366377
res: ServerResponse,
@@ -387,7 +398,11 @@ export function getOverlayMiddleware(project: Project) {
387398
const result: OriginalStackFramesResponse = await Promise.all(
388399
stackFrames.map(async (frame) => {
389400
try {
390-
const stackFrame = await createOriginalStackFrame(project, frame)
401+
const stackFrame = await createOriginalStackFrame(
402+
project,
403+
projectPath,
404+
frame
405+
)
391406
if (stackFrame === null) {
392407
return {
393408
status: 'rejected',

Diff for: packages/next/src/client/components/react-dev-overlay/server/middleware-webpack.ts

+11-1
Original file line numberDiff line numberDiff line change
@@ -471,9 +471,19 @@ async function getOriginalStackFrame({
471471
},
472472
})
473473

474+
let defaultNormalizedStackFrameLocation = frame.file
475+
if (
476+
defaultNormalizedStackFrameLocation !== null &&
477+
defaultNormalizedStackFrameLocation.startsWith('file://')
478+
) {
479+
defaultNormalizedStackFrameLocation = path.relative(
480+
rootDirectory,
481+
fileURLToPath(defaultNormalizedStackFrameLocation)
482+
)
483+
}
474484
// This stack frame is used for the one that couldn't locate the source or source mapped frame
475485
const defaultStackFrame: IgnorableStackFrame = {
476-
file: frame.file,
486+
file: defaultNormalizedStackFrameLocation,
477487
lineNumber: frame.lineNumber,
478488
column: frame.column ?? 1,
479489
methodName: frame.methodName,

Diff for: packages/next/src/server/dev/hot-reloader-turbopack.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ export async function createHotReloaderTurbopack(
161161
): Promise<NextJsHotReloaderInterface> {
162162
const dev = true
163163
const buildId = 'development'
164-
const { nextConfig, dir } = opts
164+
const { nextConfig, dir: projectPath } = opts
165165

166166
const { loadBindings } =
167167
require('../../build/swc') as typeof import('../../build/swc')
@@ -172,7 +172,7 @@ export async function createHotReloaderTurbopack(
172172
// works correctly. Normally `run-test` hides output so only will be visible when `--debug` flag is used.
173173
if (process.env.TURBOPACK && isTestMode) {
174174
require('console').log('Creating turbopack project', {
175-
dir,
175+
dir: projectPath,
176176
testMode: isTestMode,
177177
})
178178
}
@@ -207,14 +207,14 @@ export async function createHotReloaderTurbopack(
207207

208208
const project = await bindings.turbo.createProject(
209209
{
210-
projectPath: dir,
210+
projectPath: projectPath,
211211
rootPath:
212212
opts.nextConfig.experimental.turbo?.root ||
213213
opts.nextConfig.outputFileTracingRoot ||
214-
dir,
214+
projectPath,
215215
distDir,
216216
nextConfig: opts.nextConfig,
217-
jsConfig: await getTurbopackJsConfig(dir, nextConfig),
217+
jsConfig: await getTurbopackJsConfig(projectPath, nextConfig),
218218
watch: {
219219
enable: dev,
220220
pollIntervalMs: nextConfig.watchOptions?.pollIntervalMs,
@@ -244,7 +244,7 @@ export async function createHotReloaderTurbopack(
244244
}
245245
)
246246
setBundlerFindSourceMapImplementation(
247-
getSourceMapFromTurbopack.bind(null, project, dir)
247+
getSourceMapFromTurbopack.bind(null, project, projectPath)
248248
)
249249
opts.onDevServerCleanup?.(async () => {
250250
setBundlerFindSourceMapImplementation(() => undefined)
@@ -634,7 +634,7 @@ export async function createHotReloaderTurbopack(
634634
)
635635

636636
const middlewares = [
637-
getOverlayMiddleware(project),
637+
getOverlayMiddleware(project, projectPath),
638638
getSourceMapMiddleware(project),
639639
getNextErrorFeedbackMiddleware(opts.telemetry),
640640
getDevOverlayFontMiddleware(),
@@ -957,7 +957,7 @@ export async function createHotReloaderTurbopack(
957957
> =
958958
definition ??
959959
(await findPagePathData(
960-
dir,
960+
projectPath,
961961
inputPage,
962962
nextConfig.pageExtensions,
963963
opts.pagesDir,

Diff for: test/development/acceptance-app/ReactRefreshLogBox.test.ts

+18-18
Original file line numberDiff line numberDiff line change
@@ -115,15 +115,15 @@ describe('ReactRefreshLogBox app', () => {
115115
| ^",
116116
"stack": [
117117
"eval index.js (3:7)",
118-
"<FIXME-file-protocol>",
119-
"<FIXME-file-protocol>",
120-
"<FIXME-file-protocol>",
121-
"<FIXME-file-protocol>",
118+
"<FIXME-next-dist-dir>",
119+
"<FIXME-next-dist-dir>",
120+
"<FIXME-next-dist-dir>",
121+
"<FIXME-next-dist-dir>",
122122
"eval ./app/page.js",
123-
"<FIXME-file-protocol>",
124-
"<FIXME-file-protocol>",
125-
"<FIXME-file-protocol>",
126-
"<FIXME-file-protocol>",
123+
"<FIXME-next-dist-dir>",
124+
"<FIXME-next-dist-dir>",
125+
"<FIXME-next-dist-dir>",
126+
"<FIXME-next-dist-dir>",
127127
],
128128
}
129129
`)
@@ -1468,10 +1468,10 @@ describe('ReactRefreshLogBox app', () => {
14681468
"stack": [
14691469
"eval index.js (1:7)",
14701470
"<FIXME-next-dist-dir>",
1471-
"<FIXME-file-protocol>",
1471+
"<FIXME-next-dist-dir>",
14721472
"eval ./app/server/page.js",
14731473
"<FIXME-next-dist-dir>",
1474-
"<FIXME-file-protocol>",
1474+
"<FIXME-next-dist-dir>",
14751475
],
14761476
}
14771477
`)
@@ -1639,15 +1639,15 @@ export default function Home() {
16391639
| ^",
16401640
"stack": [
16411641
"eval app/utils.ts (1:7)",
1642-
"<FIXME-file-protocol>",
1643-
"<FIXME-file-protocol>",
1644-
"<FIXME-file-protocol>",
1645-
"<FIXME-file-protocol>",
1642+
"<FIXME-next-dist-dir>",
1643+
"<FIXME-next-dist-dir>",
1644+
"<FIXME-next-dist-dir>",
1645+
"<FIXME-next-dist-dir>",
16461646
"eval ./app/page.js",
1647-
"<FIXME-file-protocol>",
1648-
"<FIXME-file-protocol>",
1649-
"<FIXME-file-protocol>",
1650-
"<FIXME-file-protocol>",
1647+
"<FIXME-next-dist-dir>",
1648+
"<FIXME-next-dist-dir>",
1649+
"<FIXME-next-dist-dir>",
1650+
"<FIXME-next-dist-dir>",
16511651
],
16521652
}
16531653
`)

Diff for: test/development/acceptance/ReactRefreshLogBox.test.ts

+38-37
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,9 @@ describe('ReactRefreshLogBox', () => {
131131
| ^",
132132
"stack": [
133133
"[project]/index.js [ssr] (ecmascript) index.js (3:7)",
134-
"<FIXME-file-protocol>",
135-
"<FIXME-file-protocol>",
136-
"<FIXME-file-protocol>",
134+
"<FIXME-next-dist-dir>",
135+
"<FIXME-next-dist-dir>",
136+
"<FIXME-next-dist-dir>",
137137
],
138138
}
139139
`)
@@ -149,18 +149,18 @@ describe('ReactRefreshLogBox', () => {
149149
| ^",
150150
"stack": [
151151
"eval index.js (3:7)",
152-
"<FIXME-file-protocol>",
153-
"<FIXME-file-protocol>",
152+
"<FIXME-next-dist-dir>",
153+
"<FIXME-next-dist-dir>",
154154
"eval ./pages/index.js",
155-
"<FIXME-file-protocol>",
156-
"<FIXME-file-protocol>",
157-
"<FIXME-file-protocol>",
158-
"<FIXME-file-protocol>",
159-
"<FIXME-file-protocol>",
160-
"<FIXME-file-protocol>",
161-
"<FIXME-file-protocol>",
162-
"<FIXME-file-protocol>",
163-
"<FIXME-file-protocol>",
155+
"<FIXME-next-dist-dir>",
156+
"<FIXME-next-dist-dir>",
157+
"<FIXME-next-dist-dir>",
158+
"<FIXME-next-dist-dir>",
159+
"<FIXME-next-dist-dir>",
160+
"<FIXME-next-dist-dir>",
161+
"<FIXME-next-dist-dir>",
162+
"<FIXME-next-dist-dir>",
163+
"<FIXME-next-dist-dir>",
164164
],
165165
}
166166
`)
@@ -178,9 +178,9 @@ describe('ReactRefreshLogBox', () => {
178178
| ^",
179179
"stack": [
180180
"[project]/index.js [ssr] (ecmascript) index.js (3:7)",
181-
"<FIXME-file-protocol>",
182-
"<FIXME-file-protocol>",
183-
"<FIXME-file-protocol>",
181+
"<FIXME-next-dist-dir>",
182+
"<FIXME-next-dist-dir>",
183+
"<FIXME-next-dist-dir>",
184184
],
185185
}
186186
`)
@@ -196,18 +196,18 @@ describe('ReactRefreshLogBox', () => {
196196
| ^",
197197
"stack": [
198198
"eval index.js (3:7)",
199-
"<FIXME-file-protocol>",
200-
"<FIXME-file-protocol>",
199+
"<FIXME-next-dist-dir>",
200+
"<FIXME-next-dist-dir>",
201201
"eval ./pages/index.js",
202-
"<FIXME-file-protocol>",
203-
"<FIXME-file-protocol>",
204-
"<FIXME-file-protocol>",
205-
"<FIXME-file-protocol>",
206-
"<FIXME-file-protocol>",
207-
"<FIXME-file-protocol>",
208-
"<FIXME-file-protocol>",
209-
"<FIXME-file-protocol>",
210-
"<FIXME-file-protocol>",
202+
"<FIXME-next-dist-dir>",
203+
"<FIXME-next-dist-dir>",
204+
"<FIXME-next-dist-dir>",
205+
"<FIXME-next-dist-dir>",
206+
"<FIXME-next-dist-dir>",
207+
"<FIXME-next-dist-dir>",
208+
"<FIXME-next-dist-dir>",
209+
"<FIXME-next-dist-dir>",
210+
"<FIXME-next-dist-dir>",
211211
],
212212
}
213213
`)
@@ -284,8 +284,8 @@ describe('ReactRefreshLogBox', () => {
284284
"stack": [
285285
"FunctionDefault FunctionDefault.js (1:51)",
286286
"Set.forEach <anonymous> (0:0)",
287-
"<FIXME-file-protocol>",
288-
"<FIXME-file-protocol>",
287+
"${isTurbopack ? '<FIXME-file-protocol>' : '<FIXME-next-dist-dir>'}",
288+
"${isTurbopack ? '<FIXME-file-protocol>' : '<FIXME-next-dist-dir>'}",
289289
],
290290
}
291291
`)
@@ -302,8 +302,8 @@ describe('ReactRefreshLogBox', () => {
302302
"stack": [
303303
"FunctionDefault FunctionDefault.js (1:51)",
304304
"Set.forEach <anonymous> (0:0)",
305-
"<FIXME-file-protocol>",
306-
"<FIXME-file-protocol>",
305+
"${isTurbopack ? '<FIXME-file-protocol>' : '<FIXME-next-dist-dir>'}",
306+
"${isTurbopack ? '<FIXME-file-protocol>' : '<FIXME-next-dist-dir>'}",
307307
],
308308
}
309309
`)
@@ -413,7 +413,6 @@ describe('ReactRefreshLogBox', () => {
413413
}
414414
})
415415

416-
// Module trace is only available with webpack 5
417416
test('conversion to class component (1)', async () => {
418417
await using sandbox = await createSandbox(next)
419418
const { browser, session } = sandbox
@@ -459,6 +458,8 @@ describe('ReactRefreshLogBox', () => {
459458
`
460459
)
461460

461+
// TODO(veil): ignore-list Webpack runtime (https://linear.app/vercel/issue/NDX-945)
462+
// TODO(veil): Don't bail in Turbopack for sources outside of the project (https://linear.app/vercel/issue/NDX-944)
462463
if (isReact18) {
463464
await expect(browser).toDisplayRedbox(`
464465
{
@@ -472,8 +473,8 @@ describe('ReactRefreshLogBox', () => {
472473
"stack": [
473474
"ClickCount.render Child.js (4:11)",
474475
"Set.forEach <anonymous> (0:0)",
475-
"<FIXME-file-protocol>",
476-
"<FIXME-file-protocol>",
476+
"${isTurbopack ? '<FIXME-file-protocol>' : '<FIXME-next-dist-dir>'}",
477+
"${isTurbopack ? '<FIXME-file-protocol>' : '<FIXME-next-dist-dir>'}",
477478
],
478479
}
479480
`)
@@ -490,8 +491,8 @@ describe('ReactRefreshLogBox', () => {
490491
"stack": [
491492
"ClickCount.render Child.js (4:11)",
492493
"Set.forEach <anonymous> (0:0)",
493-
"<FIXME-file-protocol>",
494-
"<FIXME-file-protocol>",
494+
"${isTurbopack ? '<FIXME-file-protocol>' : '<FIXME-next-dist-dir>'}",
495+
"${isTurbopack ? '<FIXME-file-protocol>' : '<FIXME-next-dist-dir>'}",
495496
],
496497
}
497498
`)

0 commit comments

Comments
 (0)