-
Notifications
You must be signed in to change notification settings - Fork 27.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[NEXT-889] Unable to Test Server Components in Next.js 13 App Dir #47448
Comments
Related to #47299 |
I am also experiencing the same issue as @defrex but instead of importing Testing is raising the same Any guidance on how to fix would be much appreciated!! |
Same issue. Would love to start testing :) Or would I...... |
In that issue the explanation is that |
It's more that The NEXT-889 issue tag in the issue title means that the Next team are tracking this internally, so that's a good sign. I think one solution will be to have two Jest |
A seperate profile is a good idea. Do you have an example that works with Nextjs 13 maybe? |
No, sorry, not yet. My team was about to start looking into it but then I saw that Vercel had updated this ticket with a Linear/Jira ticket reference, so we put the idea to the side and will wait for an official docs update. If you'd like an example of using two Jest profiles then I think the 'Next Right Now' repo has an example of it. I'm on my phone at the moment but will post this comment then go and find and share a URL on my laptop… |
Ah, I was wrong, it was Blitz, not 'Next Right Now': https://github.com/blitz-js/blitz/blob/canary/packages/blitz/jest-preset.js#L50-L82 Someone has also shared an example of using |
That github comment is really nice, but even in a Node environment I get the same error. // jest.config.mjs
import nextJest from 'next/jest.js'
const createJestConfig = nextJest({
// Provide the path to your Next.js app to load next.config.js and .env files in your test environment
dir: './',
})
const clientTestConfig = {
displayName: "client",
testMatch: ["/**/*.clienttest.[jt]s?(x)"],
testEnvironment: "jest-environment-jsdom",
};
const serverTestConfig = {
displayName: "server",
testMatch: ["/**/*.servertest.[jt]s?(x)"],
testEnvironment: "jest-environment-node",
};
// Add any custom config to be passed to Jest
/** @type {import('jest').Config} */
const config = {
// Add more setup options before each test is run
projects: [await createJestConfig(clientTestConfig)(), await createJestConfig(serverTestConfig)()],
};
export default config; |
Ah yeah, jestjs/jest#13967 has some info on this. There are two things we can try (I've not tried these yet, so not sure if they actually work): Mocking Someone else pointed out how |
Confirming this also affects me. The 'Testing' section of the app beta docs is still greyed out / unpublished, so hopefully a solution is in the pipes. |
### 🧐 What's in there? At the moment, it is not possible to test code with `import 'server-only'` in app directory. When trying to load such file in jest (even with `testEnvironment: node`), the error will be: ``` ● Test suite failed to run·· x NEXT_RSC_ERR_CLIENT_IMPORT: server-only ,-[lib/util.js:1:1] 1 | /** @jest-environment node */· 2 | import 'server-only' : ^^^^^^^^^^^^^^^^^^^^ 3 | export const PI = 3.14; `----· at Object.transformSync (node_modules/next/src/build/swc/index.ts:443:25) at transformSync (node_modules/next/src/build/swc/index.ts:629:19) at Object.process (node_modules/next/src/build/swc/jest-transformer.ts:117:25) at ScriptTransformer.transformSource (node_modules/@jest/transform/build/ScriptTransformer.js:619:31) at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:765:40) at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:822:19)· ``` In a nutshell: - next/swc is looking for ‘server-only’ [text in the source](https://github.com/vercel/next.js/blob/canary/packages/next-swc/crates/core/src/react_server_components.rs#L576), and throw if not configured for server - next's jest-transformer will only configure next/swc for server [if the environment is node](https://github.com/vercel/next.js/blob/canary/packages/next/src/build/swc/jest-transformer.ts#L88) - when testing Next.js apps, your jest testEnvironment is most likely jsdom. But you can configure it [per file with docBlock](https://jestjs.io/docs/configuration#testenvironment-string), which jest-transformer ignores because it only reads the top-level configuration. This PR fixes this, by 1. reading the docblock to configure next/swc accordingly and bypass its hardcoded guard 2. mocking `server-only` so [it does not throw](https://github.com/vercel/next.js/blob/canary/packages/next/src/compiled/server-only/index.js) when loaded (jest does not read `react-server` export from package.json) Users would still have to annotate their `server-only` files with `/** @jest-environment node */` in order to test them. ### 🧪 How to test? There's a full test available: `pnpm testheadless --testPathPattern jest/server-only` Here is also a minimal reproduction: <details> <summary>app/layout.tsx</summary> ```typescript export default function RootLayout({ children }: { children: React.ReactNode }) { return (<html lang="en"><body>{children}</body></html>) } ``` </details> <details> <summary>app/page.tsx</summary> ```typescript import { PI } from '@/lib/utils' export default function Home() { return <h1>{PI}</h1> } ``` </details> <details> <summary>lib/utils.ts</summary> ```typescript import 'server-only' export const PI = 3.14 ``` </details> <details> <summary>lib/utils.test.ts</summary> ```typescript import { PI } from './utils' it('works', () => expect(PI).toEqual(3.14)) ``` </details> <details> <summary>jest.config.js</summary> ```typescript const nextJest = require('next/jest') module.exports = nextJest({ dir: './' })({ testEnvironment: 'jsdom' }) ``` </details> ### ❗ Notes to reviewers [jest-docblock](https://packagephobia.com/result?p=jest-docblock) with dependencies is only 12.5 kB. Fixes #47448
@feugy This problem still seems to be occurring when using vitest--what is the vitest equivalent of configuring server-only code for testing using |
That should also work with Vitest (along with |
This closed issue has been automatically locked because it had no new activity for 2 weeks. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you. |
Verify canary release
Provide environment information
Operating System: Platform: darwin Arch: arm64 Version: Darwin Kernel Version 22.3.0: Mon Jan 30 20:39:46 PST 2023; root:xnu-8792.81.3~2/RELEASE_ARM64_T6020 Binaries: Node: 19.7.0 npm: 9.5.0 Yarn: N/A pnpm: N/A Relevant packages: next: 13.2.5-canary.14 eslint-config-next: 13.2.4 react: 18.2.0 react-dom: 18.2.0
Which area(s) of Next.js are affected? (leave empty if unsure)
App directory (appDir: true), Jest (next/jest)
Link to the code that reproduces this issue
https://github.com/defrex/next13-jest-server-bug
To Reproduce
In the linked repo,
npm i && npx jest
The repo is just a very basic
create-next-app
project with Jest installed, using thenext/jest
config.Describe the Bug
Any test of a server-only component (or anything with a server-only component in it's import path) fails to load.
Like so,
Expected Behavior
I would expect these files/components to be testable. Or at very least, to be able to import non-component code from related files for the sake of testing.
Which browser are you using? (if relevant)
No response
How are you deploying your application? (if relevant)
No response
NEXT-889
The text was updated successfully, but these errors were encountered: