vercel / next.js

The React Framework
https://nextjs.org
MIT License
126.1k stars 26.88k forks source link

[next/jest] Executing jest with Storybook preview crashes on version 13.2.4 onwards #47866

Open vallovic opened 1 year ago

vallovic commented 1 year ago

Verify canary release

Provide environment information

Operating System:
      Platform: win32
      Arch: x64
      Version: Windows 10 Pro
    Binaries:
      Node: 18.15.0
      npm: N/A
      Yarn: N/A
      pnpm: N/A
    Relevant packages:
      next: 13.2.5-canary.28
      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)

Jest (next/jest)

Link to the code that reproduces this issue

https://github.com/vallovic/next-jest-issue

To Reproduce

Clone repository, execute npm run test and you'll see it crash with the following error. You may change next version in package.json to 13.2.3 to check that in that version it's working without any issues.

# npm run test

> test
> jest

 FAIL  components/span.test.tsx
  ● Test suite failed to run

    Cannot find module '.storybook/preview' from 'jest.setup.js'

    However, Jest was able to find:
        '.storybook/preview.ts'

    You might want to include a file extension in your import, or update your 'moduleFileExtensions', which is currently ['js', 'mjs', 'cjs', 'jsx', 'ts', 'tsx', 'json', 'node'].

    See https://jestjs.io/docs/configuration#modulefileextensions-arraystring

      4 | setProjectAnnotations(globalStorybookConfig);
      5 |

      at Resolver._throwModNotFoundError (node_modules/jest-resolve/build/resolver.js:427:11)
      at Object.<anonymous> (jest.setup.js:6:56)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        0.865 s

Describe the Bug

I'm using Storybook to write stories and leverage its use to also run unit tests. I have baseUrl/paths in my tsconfig.json thus I'm also using the moduleNameMapper in jest.config.js to keep it all working and in sync - as you may check it in the referenced repository. Up until next version 13.2.3, everything was working fine.

After updating to version 13.2.4 (and also most recent 13.2.5-canary.28), the bug above started appearing so it won't allow me to test.

This bug may be related with the changes introduce in #45815. Following those introduced changes, if I happen to remove moduleNameMapper from jest.config.js in this new version, it also doesn't work.

Referenced repository includes 3 screenshots of all the results with the different versions.

Expected Behavior

Running npm run test should not crash with an error like this since it was working flawlessly on version before.

Which browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

No response

DanProudfoot commented 1 year ago

I'm getting the same issue in similar circumstances - with Next 13.2.4, when using next/jest it seems that basically any library that I use in jest.setup.js can't be loaded. For example when doing import { setupServer } from 'msw/node'; I get the error Cannot find module '../../msw' - Obviously msw isn't a local path, it's a node module.

mizozobu commented 1 year ago

Temporary workaround is to rename .storybook to storybook. You'll have to start your storybook with -c storybook flag.

I think there is an issue importing a file whose path includes a directory that starts with ..

import test from './.a/b';
// Error: Cannot find module 'xxx/.a/b' from 'yyy'
sshah98 commented 1 year ago

Running into the same issue as DanProudfoot -- Cannot find module './@testing-library/jest-dom' from 'tests/pages/api/**'

sshah98 commented 1 year ago

Running into the same issue as DanProudfoot -- Cannot find module './@testing-library/jest-dom' from 'tests/pages/api/**'

I fixed this in my local code btw -- https://github.com/vercel/next.js/issues/40183#issuecomment-1500614550, basically my tsconfig and jest.config weren't matching up with the module mappers. I removed it all and it worked

stefcot commented 1 year ago

I have found the solution for the preview.tsx file to be taken into account :

import type { Config } from 'jest'
import path from 'path'
import nextJest from 'next/Jest'
import getJestMappersFromTSConfig from 'tsconfig-paths-jest-mapper'

const moduleNameMapper = getJestMappersFromTSConfig(
  path.resolve(__dirname, './tsconfig.paths.json')
)

const createJestConfig = nextJest({
  // Provide the path to your Next.js app to load next.config.js and .env files in your test environment
  dir: './',
})

// Add any custom config to be passed to Jest
const customJestConfig: Config = {
  preset: 'ts-jest',
  testEnvironment: 'jest-environment-jsdom',
  setupFilesAfterEnv: ['<rootDir>/jest.setup.afterEnv.ts'], // Add more setup options before each test is run
  setupFiles: ['<rootDir>/jest.setup.ts'], // Stub native javascript features
  testRegex: ['(/src/.*(test|spec))\\.[jt]sx?$'],
  // testMatch: ['**/*.test.ts?(x)'],
  testTimeout: 80_000,
  moduleNameMapper: {
    ...moduleNameMapper,
  },
}

// taken from https://github.com/vercel/next.js/issues/35634#issuecomment-1080942525
const jestConfig = async () => {
  const nextJestConfig = await createJestConfig(customJestConfig)()

  return {
    ...nextJestConfig,
    moduleNameMapper: {
      // Workaround to put our SVG stub first
      '\\.svg': '<rootDir>/src/test/svgr.mock.tsx',
      // New bug in next/Jest since Next.js v13.2.x
      // You have to specify the complete path to preview.tsx for it ot be taken into account as a module
      '\\.storybook/preview': '<rootDir>/.storybook/preview.tsx',
      ...nextJestConfig.moduleNameMapper,
    },
  }
}

export default jestConfig

That was a real thrill cause no one has this very problem