Some checks failed
Test examples / Test Examples (20) (push) Has been cancelled
Test examples / Test Examples (22) (push) Has been cancelled
Lock Threads / action (push) Has been cancelled
Trigger Release / start (push) Has been cancelled
Stale issue handler / stale (push) Has been cancelled
Update Font Data / create-pull-request (push) Has been cancelled
build-and-deploy / deploy-target (push) Has been cancelled
build-and-deploy / build (push) Has been cancelled
build-and-deploy / stable - aarch64-unknown-linux-musl - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-unknown-linux-musl - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-unknown-linux-gnu - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-unknown-linux-gnu - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-pc-windows-msvc - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-pc-windows-msvc - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-apple-darwin - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-apple-darwin - node@16 (push) Has been cancelled
build-and-deploy / build-wasm (nodejs) (push) Has been cancelled
build-and-deploy / build-wasm (web) (push) Has been cancelled
build-and-deploy / Deploy preview tarball (push) Has been cancelled
build-and-deploy / Potentially publish release (push) Has been cancelled
build-and-deploy / publish-turbopack-npm-packages (push) Has been cancelled
build-and-deploy / Deploy examples (push) Has been cancelled
build-and-deploy / thank you, build (push) Has been cancelled
build-and-deploy / Upload Turbopack Bytesize metrics to Datadog (push) Has been cancelled
Rspack Next.js development integration tests / Rspack integration tests (push) Has been cancelled
Rspack Next.js production integration tests / Rspack integration tests (push) Has been cancelled
Turbopack Next.js development integration tests / Next.js integration tests (push) Has been cancelled
Turbopack Next.js production integration tests / Next.js integration tests (push) Has been cancelled
Update Rspack test manifest / Update and upload Rspack development test manifest (push) Has been cancelled
Update Rspack test manifest / Update and upload Rspack production test manifest (push) Has been cancelled
Upload bundler test manifests to areweturboyet.com / Upload test results (push) Has been cancelled
Update React / create-pull-request (push) Has been cancelled
test-e2e-project-reset-cron / reset-test-project (push) Has been cancelled
Notify about the top 15 issues/PRs/feature requests (most reacted) in the last 90 days / run (push) Has been cancelled
433 lines
14 KiB
TypeScript
433 lines
14 KiB
TypeScript
/* eslint-env jest */
|
||
import { nextTestSetup } from 'e2e-utils'
|
||
import { createSandbox } from 'development-sandbox'
|
||
import { outdent } from 'outdent'
|
||
|
||
const isRspack = process.env.NEXT_RSPACK !== undefined
|
||
|
||
const initialFiles = new Map([
|
||
['app/_.js', ''], // app dir need to exists, otherwise the SWC RSC checks will not run
|
||
[
|
||
'pages/index.js',
|
||
outdent`
|
||
import Comp from '../components/Comp'
|
||
|
||
export default function Page() { return <Comp /> }
|
||
`,
|
||
],
|
||
[
|
||
'components/Comp.js',
|
||
outdent`
|
||
export default function Comp() {
|
||
return <p>Hello world</p>
|
||
}
|
||
`,
|
||
],
|
||
])
|
||
|
||
describe('Error Overlay for server components compiler errors in pages', () => {
|
||
const { next } = nextTestSetup({
|
||
files: {},
|
||
skipStart: true,
|
||
})
|
||
|
||
test("importing 'next/headers' in pages", async () => {
|
||
await using sandbox = await createSandbox(next, initialFiles)
|
||
const { session } = sandbox
|
||
|
||
await session.patch(
|
||
'components/Comp.js',
|
||
outdent`
|
||
import { cookies } from 'next/headers'
|
||
|
||
export default function Page() {
|
||
return <p>hello world</p>
|
||
}
|
||
`
|
||
)
|
||
|
||
await session.waitForRedbox()
|
||
await expect(session.getRedboxSource()).resolves.toMatch(
|
||
/That only works in a Server Component/
|
||
)
|
||
|
||
if (process.env.IS_TURBOPACK_TEST) {
|
||
expect(next.normalizeTestDirContent(await session.getRedboxSource()))
|
||
.toMatchInlineSnapshot(`
|
||
"./components/Comp.js (1:1)
|
||
You're importing a component that needs "next/headers". That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/app/building-your-application/rendering/server-components
|
||
> 1 | import { cookies } from 'next/headers'
|
||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||
2 |
|
||
3 | export default function Page() {
|
||
4 | return <p>hello world</p>
|
||
|
||
Ecmascript file had an error
|
||
|
||
Import traces:
|
||
Browser:
|
||
./components/Comp.js
|
||
./pages/index.js
|
||
|
||
SSR:
|
||
./components/Comp.js
|
||
./pages/index.js"
|
||
`)
|
||
} else if (isRspack) {
|
||
expect(
|
||
takeUpToString(
|
||
next.normalizeTestDirContent(await session.getRedboxSource()),
|
||
'----'
|
||
)
|
||
).toMatchInlineSnapshot(`
|
||
"./components/Comp.js
|
||
╰─▶ × Error: x You're importing a component that needs "next/headers". That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/app/building-your-application/rendering/server-components
|
||
│ |
|
||
│
|
||
│ ,-[1:1]
|
||
│ 1 | import { cookies } from 'next/headers'
|
||
│ : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||
│ 2 |
|
||
│ 3 | export default function Page() {
|
||
│ 4 | return <p>hello world</p>
|
||
│ \`----"
|
||
`)
|
||
} else {
|
||
expect(next.normalizeTestDirContent(await session.getRedboxSource()))
|
||
.toMatchInlineSnapshot(`
|
||
"./components/Comp.js
|
||
Error: x You're importing a component that needs "next/headers". That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/app/building-your-application/rendering/server-components
|
||
|
|
||
|
||
,-[1:1]
|
||
1 | import { cookies } from 'next/headers'
|
||
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||
2 |
|
||
3 | export default function Page() {
|
||
4 | return <p>hello world</p>
|
||
\`----
|
||
|
||
Import trace for requested module:
|
||
./components/Comp.js
|
||
./pages/index.js"
|
||
`)
|
||
}
|
||
})
|
||
|
||
test("importing 'server-only' in pages", async () => {
|
||
await using sandbox = await createSandbox(next, initialFiles)
|
||
const { session } = sandbox
|
||
|
||
await next.patchFile(
|
||
'components/Comp.js',
|
||
outdent`
|
||
import 'server-only'
|
||
|
||
export default function Page() {
|
||
return 'hello world'
|
||
}
|
||
`
|
||
)
|
||
|
||
await session.waitForRedbox()
|
||
await expect(session.getRedboxSource()).resolves.toMatch(
|
||
/That only works in a Server Component/
|
||
)
|
||
|
||
if (process.env.IS_TURBOPACK_TEST) {
|
||
expect(next.normalizeTestDirContent(await session.getRedboxSource()))
|
||
.toMatchInlineSnapshot(`
|
||
"./components/Comp.js (1:1)
|
||
You're importing a component that needs "server-only". That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/app/building-your-application/rendering/server-components
|
||
> 1 | import 'server-only'
|
||
| ^^^^^^^^^^^^^^^^^^^^
|
||
2 |
|
||
3 | export default function Page() {
|
||
4 | return 'hello world'
|
||
|
||
Ecmascript file had an error
|
||
|
||
Import traces:
|
||
Browser:
|
||
./components/Comp.js
|
||
./pages/index.js
|
||
|
||
SSR:
|
||
./components/Comp.js
|
||
./pages/index.js"
|
||
`)
|
||
} else if (isRspack) {
|
||
expect(
|
||
takeUpToString(
|
||
next.normalizeTestDirContent(await session.getRedboxSource()),
|
||
'----'
|
||
)
|
||
).toMatchInlineSnapshot(`
|
||
"./components/Comp.js
|
||
╰─▶ × Error: x You're importing a component that needs "server-only". That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/app/building-your-application/rendering/server-components
|
||
│ |
|
||
│
|
||
│ ,-[1:1]
|
||
│ 1 | import 'server-only'
|
||
│ : ^^^^^^^^^^^^^^^^^^^^
|
||
│ 2 |
|
||
│ 3 | export default function Page() {
|
||
│ 4 | return 'hello world'
|
||
│ \`----"
|
||
`)
|
||
} else {
|
||
expect(
|
||
takeUpToString(
|
||
next.normalizeTestDirContent(await session.getRedboxSource()),
|
||
'Import trace for requested module:'
|
||
)
|
||
).toMatchInlineSnapshot(`
|
||
"./components/Comp.js
|
||
Error: x You're importing a component that needs "server-only". That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/app/building-your-application/rendering/server-components
|
||
|
|
||
|
||
,-[1:1]
|
||
1 | import 'server-only'
|
||
: ^^^^^^^^^^^^^^^^^^^^
|
||
2 |
|
||
3 | export default function Page() {
|
||
4 | return 'hello world'
|
||
\`----
|
||
|
||
Import trace for requested module:"
|
||
`)
|
||
}
|
||
})
|
||
|
||
test("importing after from 'next/server' in pages", async () => {
|
||
await using sandbox = await createSandbox(next, initialFiles)
|
||
const { session } = sandbox
|
||
|
||
await next.patchFile(
|
||
'components/Comp.js',
|
||
outdent`
|
||
import { after } from 'next/server'
|
||
|
||
export default function Page() {
|
||
return 'hello world'
|
||
}
|
||
`
|
||
)
|
||
|
||
await session.waitForRedbox()
|
||
await expect(session.getRedboxSource()).resolves.toMatch(
|
||
/That only works in a Server Component/
|
||
)
|
||
|
||
if (process.env.IS_TURBOPACK_TEST) {
|
||
expect(next.normalizeTestDirContent(await session.getRedboxSource()))
|
||
.toMatchInlineSnapshot(`
|
||
"./components/Comp.js (1:10)
|
||
You're importing a component that needs "after". That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/app/building-your-application/rendering/server-components
|
||
> 1 | import { after } from 'next/server'
|
||
| ^^^^^
|
||
2 |
|
||
3 | export default function Page() {
|
||
4 | return 'hello world'
|
||
|
||
Ecmascript file had an error
|
||
|
||
Import traces:
|
||
Browser:
|
||
./components/Comp.js
|
||
./pages/index.js
|
||
|
||
SSR:
|
||
./components/Comp.js
|
||
./pages/index.js"
|
||
`)
|
||
} else if (isRspack) {
|
||
expect(
|
||
takeUpToString(
|
||
next.normalizeTestDirContent(await session.getRedboxSource()),
|
||
'----'
|
||
)
|
||
).toMatchInlineSnapshot(`
|
||
"./components/Comp.js
|
||
╰─▶ × Error: x You're importing a component that needs "after". That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/app/building-your-application/rendering/server-components
|
||
│ |
|
||
│
|
||
│ ,-[1:1]
|
||
│ 1 | import { after } from 'next/server'
|
||
│ : ^^^^^
|
||
│ 2 |
|
||
│ 3 | export default function Page() {
|
||
│ 4 | return 'hello world'
|
||
│ \`----"
|
||
`)
|
||
} else {
|
||
expect(
|
||
takeUpToString(
|
||
next.normalizeTestDirContent(await session.getRedboxSource()),
|
||
'Import trace for requested module:'
|
||
)
|
||
).toMatchInlineSnapshot(`
|
||
"./components/Comp.js
|
||
Error: x You're importing a component that needs "after". That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/app/building-your-application/rendering/server-components
|
||
|
|
||
|
||
,-[1:1]
|
||
1 | import { after } from 'next/server'
|
||
: ^^^^^
|
||
2 |
|
||
3 | export default function Page() {
|
||
4 | return 'hello world'
|
||
\`----
|
||
|
||
Import trace for requested module:"
|
||
`)
|
||
}
|
||
})
|
||
|
||
test("importing 'next/root-params' in pages", async () => {
|
||
const files = new Map([
|
||
...initialFiles,
|
||
[
|
||
'components/Comp.js',
|
||
outdent`
|
||
import { foo } from 'next/root-params'
|
||
|
||
export default function Page() {
|
||
return 'hello world'
|
||
}
|
||
`,
|
||
],
|
||
[
|
||
// the import is guarded behind an experimental flag
|
||
'next.config.js',
|
||
outdent`
|
||
module.exports = { experimental: { rootParams: true } }
|
||
`,
|
||
],
|
||
])
|
||
await using sandbox = await createSandbox(next, files)
|
||
const { session } = sandbox
|
||
|
||
await session.waitForRedbox()
|
||
await expect(session.getRedboxSource()).resolves.toMatch(
|
||
/That only works in a Server Component/
|
||
)
|
||
|
||
if (process.env.IS_TURBOPACK_TEST) {
|
||
expect(next.normalizeTestDirContent(await session.getRedboxSource()))
|
||
.toMatchInlineSnapshot(`
|
||
"./components/Comp.js (1:1)
|
||
You're importing a component that needs "next/root-params". That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/app/building-your-application/rendering/server-components
|
||
> 1 | import { foo } from 'next/root-params'
|
||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||
2 |
|
||
3 | export default function Page() {
|
||
4 | return 'hello world'
|
||
|
||
Ecmascript file had an error
|
||
|
||
Import traces:
|
||
Browser:
|
||
./components/Comp.js
|
||
./pages/index.js
|
||
|
||
SSR:
|
||
./components/Comp.js
|
||
./pages/index.js"
|
||
`)
|
||
} else if (isRspack) {
|
||
expect(
|
||
takeUpToString(
|
||
next.normalizeTestDirContent(await session.getRedboxSource()),
|
||
'----'
|
||
)
|
||
).toMatchInlineSnapshot(`
|
||
"./components/Comp.js
|
||
╰─▶ × Error: x You're importing a component that needs "next/root-params". That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/app/building-your-application/rendering/server-components
|
||
│ |
|
||
│
|
||
│ ,-[1:1]
|
||
│ 1 | import { foo } from 'next/root-params'
|
||
│ : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||
│ 2 |
|
||
│ 3 | export default function Page() {
|
||
│ 4 | return 'hello world'
|
||
│ \`----"
|
||
`)
|
||
} else {
|
||
expect(
|
||
takeUpToString(
|
||
next.normalizeTestDirContent(await session.getRedboxSource()),
|
||
'Import trace for requested module:'
|
||
)
|
||
).toMatchInlineSnapshot(`
|
||
"./components/Comp.js
|
||
Error: x You're importing a component that needs "next/root-params". That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/app/building-your-application/rendering/server-components
|
||
|
|
||
|
||
,-[1:1]
|
||
1 | import { foo } from 'next/root-params'
|
||
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||
2 |
|
||
3 | export default function Page() {
|
||
4 | return 'hello world'
|
||
\`----"
|
||
`)
|
||
}
|
||
})
|
||
|
||
describe("importing 'next/cache' APIs in pages", () => {
|
||
test.each([
|
||
'revalidatePath',
|
||
'revalidateTag',
|
||
'cacheLife',
|
||
'cacheTag',
|
||
'revalidatePath',
|
||
'revalidateTag',
|
||
])('%s is not allowed', async (api) => {
|
||
await using sandbox = await createSandbox(next, initialFiles)
|
||
const { session } = sandbox
|
||
|
||
await next.patchFile(
|
||
'components/Comp.js',
|
||
outdent`
|
||
import { ${api} } from 'next/cache'
|
||
|
||
export default function Page() {
|
||
return 'hello world'
|
||
}
|
||
`
|
||
)
|
||
|
||
await session.waitForRedbox()
|
||
await expect(session.getRedboxSource()).resolves.toMatch(
|
||
`You're importing a component that needs "${api}". That only works in a Server Component which is not supported in the pages/ directory.`
|
||
)
|
||
})
|
||
|
||
test.each([
|
||
'unstable_cache', // useless in client, but doesn't technically error
|
||
'unstable_noStore', // no-op in client, but allowed for legacy reasons
|
||
])('%s is allowed', async (api) => {
|
||
await using sandbox = await createSandbox(next, initialFiles)
|
||
const { session } = sandbox
|
||
|
||
await next.patchFile(
|
||
'components/Comp.js',
|
||
outdent`
|
||
import { ${api} } from 'next/cache'
|
||
|
||
export default function Page() {
|
||
return 'hello world'
|
||
}
|
||
`
|
||
)
|
||
|
||
await session.waitForNoRedbox()
|
||
})
|
||
})
|
||
})
|
||
|
||
const takeUpToString = (text: string, str: string): string =>
|
||
text.includes(str) ? text.slice(0, text.indexOf(str) + str.length) : text
|