Skip to content

Commit

Permalink
Turbopack: improve stack trace in overlay (#70343)
Browse files Browse the repository at this point in the history
## Before:

<img width="965" alt="Bildschirmfoto 2024-09-23 um 14 55 16"
src="https://github.com/user-attachments/assets/26aabfdd-0e43-4dd2-a025-5eaf6a717043">


## After:
<img width="972" alt="Bildschirmfoto 2024-09-23 um 14 52 54"
src="https://github.com/user-attachments/assets/3b7ce28a-c2ea-475b-ab53-ed9838546400">

## The whole Turbopack module registry is hidden in `Next.js`:
<img width="612" alt="Bildschirmfoto 2024-09-23 um 14 53 04"
src="https://github.com/user-attachments/assets/a38295ad-90a7-49b2-a272-661e0b80bfbb">
  • Loading branch information
mischnic authored Sep 24, 2024
1 parent 1fa8e23 commit 21f0c30
Show file tree
Hide file tree
Showing 160 changed files with 1,628 additions and 1,542 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ export function findSourcePackage({
return 'react'
} else if (nextInternalsRe.test(file)) {
return 'next'
} else if (file.startsWith('[turbopack]/')) {
return 'next'
}
}

Expand Down
66 changes: 65 additions & 1 deletion test/development/acceptance-app/ReactRefreshLogBox.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
check,
describeVariants as describe,
expandCallStack,
getRedboxCallStackCollapsed,
retry,
} from 'next-test-utils'
import path from 'path'
Expand Down Expand Up @@ -218,7 +219,6 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {

await session.assertHasRedbox()

console.log({ isTurbopack })
const source = next.normalizeTestDirContent(await session.getRedboxSource())
if (isTurbopack) {
expect(source).toEqual(outdent`
Expand Down Expand Up @@ -1208,4 +1208,68 @@ export default function Home() {

await cleanup()
})

test('Should collapse bundler internal stack frames', async () => {
const { session, browser, cleanup } = await sandbox(
next,
new Map([
[
'app/utils.ts',
`throw new Error('utils error')
export function foo(){}`,
],
[
'app/page.js',
`"use client";
import { foo } from "./utils";
export default function Home() {
foo();
return "hello";
}`,
],
])
)

await session.assertHasRedbox()

let stack = next.normalizeTestDirContent(
await getRedboxCallStackCollapsed(browser)
)
if (isTurbopack) {
expect(stack).toMatchInlineSnapshot(`
"app/utils.ts (1:7) @ [project]/app/utils.ts [app-client] (ecmascript)
---
Next.js
---
[project]/app/page.js [app-client] (ecmascript)
app/page.js (0:0)
---
Next.js
---
React"
`)
} else {
expect(stack).toMatchInlineSnapshot(`
"app/utils.ts (1:7) @ eval
---
(app-pages-browser)/./app/utils.ts
file://TEST_DIR/.next/static/chunks/app/page.js (39:1)
---
Next.js
---
eval
(app-pages-browser)/./app/page.js
---
(app-pages-browser)/./app/page.js
file://TEST_DIR/.next/static/chunks/app/page.js (28:1)
---
Next.js
---
React"
`)
}

await cleanup()
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ exports[`ReactRefreshLogBox app turbo logbox: anchors links in error messages 6`
exports[`ReactRefreshLogBox app turbo logbox: anchors links in error messages 7`] = `"https://nextjs.org/"`;
exports[`ReactRefreshLogBox app turbo module init error not shown 1`] = `
"index.js (3:7) @ <unknown>
"index.js (3:7) @ [project]/index.js [app-client] (ecmascript)
1 | // top offset for snapshot
2 | import * as React from 'react';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ exports[`ReactRefreshLogBox turbo logbox: anchors links in error messages 8`] =
exports[`ReactRefreshLogBox turbo logbox: anchors links in error messages 10`] = `"https://nextjs.org/"`;
exports[`ReactRefreshLogBox turbo module init error not shown 1`] = `
"index.js (3:7) @ <unknown>
"index.js (3:7) @ [project]/index.js [ssr] (ecmascript)
1 | // top offset for snapshot
2 | import * as React from 'react';
Expand Down
8 changes: 4 additions & 4 deletions test/development/app-dir/ssr-in-rsc/ssr-in-rsc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ describe('react-dom/server in React Server environment', () => {
expect(redbox).toMatchInlineSnapshot(`
{
"description": "Error: react-dom/server is not supported in React Server Components.",
"source": "app/exports/app-code/react-dom-server-node-explicit/page.js (0:0) @ <unknown>
"source": "app/exports/app-code/react-dom-server-node-explicit/page.js (0:0) @ [project]/app/exports/app-code/react-dom-server-node-explicit/page.js [app-rsc] (ecmascript)
1 | import * as ReactDOMServerNode from 'react-dom/server.node'
2 | // Fine to drop once React is on ESM
Expand Down Expand Up @@ -407,7 +407,7 @@ describe('react-dom/server in React Server environment', () => {
expect(redbox).toMatchInlineSnapshot(`
{
"description": "Error: react-dom/server is not supported in React Server Components.",
"source": "internal-pkg/server.node.js (0:0) @ <unknown>
"source": "internal-pkg/server.node.js (0:0) @ [project]/internal-pkg/server.node.js [app-rsc] (ecmascript)
1 | import * as ReactDOMServerEdge from 'react-dom/server.node'
2 | // Fine to drop once React is on ESM
Expand Down Expand Up @@ -678,7 +678,7 @@ describe('react-dom/server in React Server environment', () => {
expect(redbox).toMatchInlineSnapshot(`
{
"description": "Error: react-dom/server is not supported in React Server Components.",
"source": "internal-pkg/server.node.js (0:0) @ <unknown>
"source": "internal-pkg/server.node.js (0:0) @ [project]/internal-pkg/server.node.js [app-rsc] (ecmascript)
1 | import * as ReactDOMServerEdge from 'react-dom/server.node'
2 | // Fine to drop once React is on ESM
Expand Down Expand Up @@ -710,7 +710,7 @@ describe('react-dom/server in React Server environment', () => {
expect(redbox).toMatchInlineSnapshot(`
{
"description": "Error: react-dom/server is not supported in React Server Components.",
"source": "internal-pkg/server.node.js (0:0) @ <unknown>
"source": "internal-pkg/server.node.js (0:0) @ [project]/internal-pkg/server.node.js [app-rsc] (ecmascript)
1 | import * as ReactDOMServerEdge from 'react-dom/server.node'
2 | // Fine to drop once React is on ESM
Expand Down
16 changes: 11 additions & 5 deletions test/development/middleware-errors/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import stripAnsi from 'strip-ansi'
import { nextTestSetup } from 'e2e-utils'

describe('middleware - development errors', () => {
const { next } = nextTestSetup({
const { next, isTurbopack } = nextTestSetup({
files: __dirname,
env: { __NEXT_TEST_WITH_DEVTOOL: '1' },
})
Expand All @@ -33,7 +33,7 @@ describe('middleware - development errors', () => {
await next.fetch('/')
const output = stripAnsi(next.cliOutput)
await check(() => {
if (process.env.TURBOPACK) {
if (isTurbopack) {
expect(stripAnsi(next.cliOutput)).toMatch(
/middleware.js \(\d+:\d+\) @ __TURBOPACK__default__export__/
)
Expand Down Expand Up @@ -152,9 +152,15 @@ describe('middleware - development errors', () => {
await next.fetch('/')
const output = stripAnsi(next.cliOutput)
await check(() => {
expect(stripAnsi(next.cliOutput)).toMatch(
/middleware.js \(\d+:\d+\) @ <unknown>/
)
if (isTurbopack) {
expect(stripAnsi(next.cliOutput)).toMatch(
/middleware.js \(\d+:\d+\) @ \[project\]\/middleware\.js \[middleware\] \(ecmascript\)/
)
} else {
expect(stripAnsi(next.cliOutput)).toMatch(
/middleware.js \(\d+:\d+\) @ <unknown>/
)
}
expect(stripAnsi(next.cliOutput)).toMatch(/booooom!/)
return 'success'
}, 'success')
Expand Down
19 changes: 18 additions & 1 deletion test/lib/next-test-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1242,7 +1242,7 @@ export async function getRedboxCallStack(
): Promise<string> {
await browser.waitForElementByCss('[data-nextjs-call-stack-frame]', 30000)

const callStackFrameElements: any = await browser.elementsByCss(
const callStackFrameElements = await browser.elementsByCss(
'[data-nextjs-call-stack-frame]'
)
const callStackFrameTexts = await Promise.all(
Expand All @@ -1252,6 +1252,23 @@ export async function getRedboxCallStack(
return callStackFrameTexts.join('\n').trim()
}

export async function getRedboxCallStackCollapsed(
browser: BrowserInterface
): Promise<string> {
await browser.waitForElementByCss('.nextjs-container-errors-body', 30000)

const callStackFrameElements = await browser.elementsByCss(
'.nextjs-container-errors-body > [data-nextjs-codeframe] > :first-child, ' +
'.nextjs-container-errors-body > [data-nextjs-call-stack-frame], ' +
'.nextjs-container-errors-body > [data-nextjs-collapsed-call-stack-details] > summary'
)
const callStackFrameTexts = await Promise.all(
callStackFrameElements.map((f) => f.innerText())
)

return callStackFrameTexts.join('\n---\n').trim()
}

export async function getVersionCheckerText(
browser: BrowserInterface
): Promise<string> {
Expand Down
11 changes: 4 additions & 7 deletions turbopack/crates/turbopack-ecmascript/src/chunk/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,15 +127,16 @@ impl EcmascriptChunkItemContent {
let mut code = CodeBuilder::default();
let args = FormatIter(|| args.iter().copied().intersperse(", "));
if this.options.this {
writeln!(code, "(function({{ {} }}) {{ !function() {{", args,)?;
code += "(function(__turbopack_context__) {\n";
} else {
writeln!(code, "(({{ {} }}) => (() => {{", args,)?;
code += "((__turbopack_context__) => {\n";
}
if this.options.strict {
code += "\"use strict\";\n\n";
} else {
code += "\n";
}
writeln!(code, "var {{ {} }} = __turbopack_context__;", args)?;

if this.options.async_module.is_some() {
code += "__turbopack_async_module__(async (__turbopack_handle_async_dependencies__, \
Expand All @@ -153,11 +154,7 @@ impl EcmascriptChunkItemContent {
)?;
}

if this.options.this {
code += "\n}.call(this) })";
} else {
code += "\n})())";
}
code += "})";
Ok(code.build().cell())
}
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 21f0c30

Please sign in to comment.