rsnext/test/development/acceptance-app/rsc-runtime-errors.test.ts
Jiachi Liu 9d150b116d
Loose RSC import restrictions for 3rd party packages (#56501)
When we landed #51179 it broke library like `apollo-client` as it's bundling client hooks into RSC bundle, so our RSC linter caught them and reported fatal errors. But those client hook APIs won't get executed in RSC. The original purpose of erroring on invalid hooks for server & client components was to catch bugs easier, but it might be too strict for the 3rd party libraries like `apollo-client` due to few reasons. 

We changed the rules only applying on user land source code. For 3rd party packages if they're not being imported correctly into proper server or client components, we're still showing runtime errors instead of fatal build errors.

x-ref: https://github.com/apollographql/apollo-client/issues/10974
Closes NEXT-1673
2023-10-05 23:59:22 +00:00

80 lines
2.3 KiB
TypeScript

import path from 'path'
import { outdent } from 'outdent'
import { FileRef, createNextDescribe } from 'e2e-utils'
import {
check,
getRedboxDescription,
hasRedbox,
shouldRunTurboDevTest,
} from 'next-test-utils'
createNextDescribe(
'Error overlay - RSC runtime errors',
{
files: new FileRef(path.join(__dirname, 'fixtures', 'rsc-runtime-errors')),
packageJson: {
scripts: {
setup: 'cp -r ./node_modules_bak/* ./node_modules',
build: 'yarn setup && next build',
dev: `yarn setup && next ${
shouldRunTurboDevTest() ? 'dev --turbo' : 'dev'
}`,
start: 'next start',
},
},
installCommand: 'yarn',
startCommand: (global as any).isNextDev ? 'yarn dev' : 'yarn start',
},
({ next }) => {
it('should show runtime errors if invalid client API from node_modules is executed', async () => {
await next.patchFile(
'app/server/page.js',
outdent`
import { callClientApi } from 'client-package'
export default function Page() {
callClientApi()
return 'page'
}
`
)
const browser = await next.browser('/server')
await check(
async () => ((await hasRedbox(browser, true)) ? 'success' : 'fail'),
/success/
)
const errorDescription = await getRedboxDescription(browser)
expect(errorDescription).toContain(
`Error: useState only works in Client Components. Add the "use client" directive at the top of the file to use it. Read more: https://nextjs.org/docs/messages/react-client-hook-in-server-component`
)
})
it('should show runtime errors if invalid server API from node_modules is executed', async () => {
await next.patchFile(
'app/client/page.js',
outdent`
'use client'
import { callServerApi } from 'server-package'
export default function Page() {
callServerApi()
return 'page'
}
`
)
const browser = await next.browser('/client')
await check(
async () => ((await hasRedbox(browser, true)) ? 'success' : 'fail'),
/success/
)
const errorDescription = await getRedboxDescription(browser)
expect(errorDescription).toContain(
`Error: Invariant: cookies() expects to have requestAsyncStorage, none available.`
)
})
}
)