mirror of
https://github.com/vercel/next.js.git
synced 2026-09-20 02:25:18 +08:00
d7aa66c345
### Why? Should come up with better solution that does not block PRs with git conflict x-ref: https://vercel.slack.com/archives/C02CDC2ALJH/p1785263902728189?thread_ts=1785263687.502649&cid=C02CDC2ALJH ### How? - Delete `errors.json`, the error-code SWC plugin, generated WASM, merge driver, and validation/build tooling. - Stop attaching error codes to server-rendering digests, redboxes, and telemetry; native `Error.code` and `Error.name` remain available where applicable. - Remove the development-overlay error feedback UI, middleware, and telemetry event that depended on stable codes. - Update fixtures, snapshots, and guidance for code-free errors and numeric-only digests. <!-- NEXT_JS_LLM -->
316 lines
9.4 KiB
TypeScript
316 lines
9.4 KiB
TypeScript
import { createSandbox } from 'development-sandbox'
|
||
import { FileRef, nextTestSetup } from 'e2e-utils'
|
||
import { outdent } from 'outdent'
|
||
import path from 'path'
|
||
|
||
const isRspack = process.env.NEXT_RSPACK !== undefined
|
||
|
||
describe('ReactRefreshLogBox _app _document', () => {
|
||
const { isTurbopack, next } = nextTestSetup({
|
||
files: new FileRef(path.join(__dirname, 'fixtures', 'default-template')),
|
||
skipStart: true,
|
||
})
|
||
|
||
test('empty _app shows logbox', async () => {
|
||
await using sandbox = await createSandbox(
|
||
next,
|
||
new Map([['pages/_app.js', ``]])
|
||
)
|
||
const { browser, session } = sandbox
|
||
await expect(browser).toDisplayRedbox(`
|
||
{
|
||
"description": "The default export is not a React Component in page: "/_app"",
|
||
"environmentLabel": null,
|
||
"label": "Runtime Error",
|
||
"source": null,
|
||
"stack": [],
|
||
}
|
||
`)
|
||
|
||
await session.patch(
|
||
'pages/_app.js',
|
||
outdent`
|
||
function MyApp({ Component, pageProps }) {
|
||
return <Component {...pageProps} />;
|
||
}
|
||
export default MyApp
|
||
`
|
||
)
|
||
await session.waitForNoRedbox()
|
||
})
|
||
|
||
test('empty _document shows logbox', async () => {
|
||
await using sandbox = await createSandbox(
|
||
next,
|
||
new Map([['pages/_document.js', ``]])
|
||
)
|
||
const { browser, session } = sandbox
|
||
|
||
await expect(browser).toDisplayRedbox(`
|
||
{
|
||
"description": "The default export is not a React Component in page: "/_document"",
|
||
"environmentLabel": null,
|
||
"label": "Runtime Error",
|
||
"source": null,
|
||
"stack": [],
|
||
}
|
||
`)
|
||
|
||
await session.patch(
|
||
'pages/_document.js',
|
||
outdent`
|
||
import Document, { Html, Head, Main, NextScript } from 'next/document'
|
||
|
||
class MyDocument extends Document {
|
||
static async getInitialProps(ctx) {
|
||
const initialProps = await Document.getInitialProps(ctx)
|
||
return { ...initialProps }
|
||
}
|
||
|
||
render() {
|
||
return (
|
||
<Html>
|
||
<Head />
|
||
<body>
|
||
<Main />
|
||
<NextScript />
|
||
</body>
|
||
</Html>
|
||
)
|
||
}
|
||
}
|
||
|
||
export default MyDocument
|
||
`
|
||
)
|
||
await session.waitForNoRedbox()
|
||
})
|
||
|
||
test('_app syntax error shows logbox', async () => {
|
||
await using sandbox = await createSandbox(
|
||
next,
|
||
new Map([
|
||
[
|
||
'pages/_app.js',
|
||
outdent`
|
||
function MyApp({ Component, pageProps }) {
|
||
return <<Component {...pageProps} />;
|
||
}
|
||
export default MyApp
|
||
`,
|
||
],
|
||
])
|
||
)
|
||
const { browser, session } = sandbox
|
||
|
||
if (isTurbopack) {
|
||
await expect(browser).toDisplayRedbox(`
|
||
{
|
||
"description": "Expression expected",
|
||
"environmentLabel": null,
|
||
"label": "Build Error",
|
||
"source": "./pages/_app.js (2:10)
|
||
Error: Expression expected
|
||
> 2 | return <<Component {...pageProps} />;
|
||
| ^^",
|
||
"stack": [],
|
||
}
|
||
`)
|
||
} else if (isRspack) {
|
||
await expect({ browser, next }).toDisplayRedbox(`
|
||
{
|
||
"description": " ╰─▶ × Error: x Expression expected",
|
||
"environmentLabel": null,
|
||
"label": "Build Error",
|
||
"source": "./pages/_app.js
|
||
╰─▶ × Error: x Expression expected
|
||
│ ,-[2:1]
|
||
│ 1 | function MyApp({ Component, pageProps }) {
|
||
│ 2 | return <<Component {...pageProps} />;
|
||
│ : ^^
|
||
│ 3 | }
|
||
│ 4 | export default MyApp
|
||
│ \`----
|
||
│ x Expected ';', got '{'
|
||
│ ,-[2:1]
|
||
│ 1 | function MyApp({ Component, pageProps }) {
|
||
│ 2 | return <<Component {...pageProps} />;
|
||
│ : ^
|
||
│ 3 | }
|
||
│ 4 | export default MyApp
|
||
│ \`----
|
||
│
|
||
│
|
||
│ Caused by:
|
||
│ Syntax Error",
|
||
"stack": [],
|
||
}
|
||
`)
|
||
} else {
|
||
await expect(browser).toDisplayRedbox(`
|
||
{
|
||
"description": " x Expression expected",
|
||
"environmentLabel": null,
|
||
"label": "Build Error",
|
||
"source": "./pages/_app.js
|
||
Error: x Expression expected
|
||
,-[2:1]
|
||
1 | function MyApp({ Component, pageProps }) {
|
||
2 | return <<Component {...pageProps} />;
|
||
: ^^
|
||
3 | }
|
||
4 | export default MyApp
|
||
\`----
|
||
x Expected ';', got '{'
|
||
,-[2:1]
|
||
1 | function MyApp({ Component, pageProps }) {
|
||
2 | return <<Component {...pageProps} />;
|
||
: ^
|
||
3 | }
|
||
4 | export default MyApp
|
||
\`----
|
||
Caused by:
|
||
Syntax Error",
|
||
"stack": [],
|
||
}
|
||
`)
|
||
}
|
||
|
||
await session.patch(
|
||
'pages/_app.js',
|
||
outdent`
|
||
function MyApp({ Component, pageProps }) {
|
||
return <Component {...pageProps} />;
|
||
}
|
||
export default MyApp
|
||
`
|
||
)
|
||
await session.waitForNoRedbox()
|
||
})
|
||
|
||
test('_document syntax error shows logbox', async () => {
|
||
await using sandbox = await createSandbox(
|
||
next,
|
||
new Map([
|
||
[
|
||
'pages/_document.js',
|
||
outdent`
|
||
import Document, { Html, Head, Main, NextScript } from 'next/document'
|
||
|
||
class MyDocument extends Document {{
|
||
static async getInitialProps(ctx) {
|
||
const initialProps = await Document.getInitialProps(ctx)
|
||
return { ...initialProps }
|
||
}
|
||
|
||
render() {
|
||
return (
|
||
<Html>
|
||
<Head />
|
||
<body>
|
||
<Main />
|
||
<NextScript />
|
||
</body>
|
||
</Html>
|
||
)
|
||
}
|
||
}
|
||
|
||
export default MyDocument
|
||
`,
|
||
],
|
||
])
|
||
)
|
||
const { browser, session } = sandbox
|
||
if (isTurbopack) {
|
||
await expect(browser).toDisplayRedbox(`
|
||
{
|
||
"description": "Unexpected token \`{\`. Expected identifier, string literal, numeric literal or [ for the computed key",
|
||
"environmentLabel": null,
|
||
"label": "Build Error",
|
||
"source": "./pages/_document.js (3:36)
|
||
Error: Unexpected token \`{\`. Expected identifier, string literal, numeric literal or [ for the computed key
|
||
> 3 | class MyDocument extends Document {{
|
||
| ^",
|
||
"stack": [],
|
||
}
|
||
`)
|
||
} else if (isRspack) {
|
||
await expect({ browser, next }).toDisplayRedbox(`
|
||
{
|
||
"description": " ╰─▶ × Error: x Unexpected token \`{\`. Expected identifier, string literal, numeric literal or [ for the computed key",
|
||
"environmentLabel": null,
|
||
"label": "Build Error",
|
||
"source": "./pages/_document.js
|
||
╰─▶ × Error: x Unexpected token \`{\`. Expected identifier, string literal, numeric literal or [ for the computed key
|
||
│ ,-[3:1]
|
||
│ 1 | import Document, { Html, Head, Main, NextScript } from 'next/document'
|
||
│ 2 |
|
||
│ 3 | class MyDocument extends Document {{
|
||
│ : ^
|
||
│ 4 | static async getInitialProps(ctx) {
|
||
│ 5 | const initialProps = await Document.getInitialProps(ctx)
|
||
│ 6 | return { ...initialProps }
|
||
│ \`----
|
||
│
|
||
│
|
||
│ Caused by:
|
||
│ Syntax Error",
|
||
"stack": [],
|
||
}
|
||
`)
|
||
} else {
|
||
await expect(browser).toDisplayRedbox(`
|
||
{
|
||
"description": " x Unexpected token \`{\`. Expected identifier, string literal, numeric literal or [ for the computed key",
|
||
"environmentLabel": null,
|
||
"label": "Build Error",
|
||
"source": "./pages/_document.js
|
||
Error: x Unexpected token \`{\`. Expected identifier, string literal, numeric literal or [ for the computed key
|
||
,-[3:1]
|
||
1 | import Document, { Html, Head, Main, NextScript } from 'next/document'
|
||
2 |
|
||
3 | class MyDocument extends Document {{
|
||
: ^
|
||
4 | static async getInitialProps(ctx) {
|
||
5 | const initialProps = await Document.getInitialProps(ctx)
|
||
6 | return { ...initialProps }
|
||
\`----
|
||
Caused by:
|
||
Syntax Error",
|
||
"stack": [],
|
||
}
|
||
`)
|
||
}
|
||
|
||
await session.patch(
|
||
'pages/_document.js',
|
||
outdent`
|
||
import Document, { Html, Head, Main, NextScript } from 'next/document'
|
||
|
||
class MyDocument extends Document {
|
||
static async getInitialProps(ctx) {
|
||
const initialProps = await Document.getInitialProps(ctx)
|
||
return { ...initialProps }
|
||
}
|
||
|
||
render() {
|
||
return (
|
||
<Html>
|
||
<Head />
|
||
<body>
|
||
<Main />
|
||
<NextScript />
|
||
</body>
|
||
</Html>
|
||
)
|
||
}
|
||
}
|
||
|
||
export default MyDocument
|
||
`
|
||
)
|
||
await session.waitForNoRedbox()
|
||
})
|
||
})
|