next.js: Jest tests failing when testing components with dynamic import in Next 10.2.0

What version of Next.js are you using?

10.2.0

What version of Node.js are you using?

14

What browser are you using?

N/A (but JSDOM in the test runner)

What operating system are you using?

macos linux

How are you deploying your application?

Pre deploy failure

Describe the Bug

I’m still putting together a minimal reproduction case (will post shortly), but(added) My jest tests that test rendering of components that make use of next/dynamic began failing on next 10.2.0.

The error:

project % npx jest components/header/header.test.jsx
 FAIL  components/header/header.test.jsx
  ● Test suite failed to run

    /project/components/header/header.jsx: The "from" argument must be of type string. Received undefined

      at Import (node_modules/next/build/babel/plugins/react-loadable-plugin.ts:154:21)
      at NodePath._call (node_modules/@babel/traverse/lib/path/context.js:55:20)
      at NodePath.call (node_modules/@babel/traverse/lib/path/context.js:42:17)
      at NodePath.visit (node_modules/@babel/traverse/lib/path/context.js:92:31)
      at TraversalContext.visitQueue (node_modules/@babel/traverse/lib/context.js:116:16)
      at TraversalContext.visitSingle (node_modules/@babel/traverse/lib/context.js:85:19)
      at TraversalContext.visit (node_modules/@babel/traverse/lib/context.js:144:19)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        2.54 s
Ran all test suites matching /components\/header\/header.test.jsx/i.

The simplified component in question:

import dynamic from 'next/dynamic'

const SomeDynamicComp = dynamic(() =>
  import('./some-dynamic-comp').then((mod) => mod.SomeDynamicComp),
{ ssr: false })

export function SomeComp () {
  return (
    <div>
      Hello world
      <SomeDynamicComp />
    </div>
    )
}

This is the code that causes the test to fail with the above error:

const SomeDynamicComp = dynamic(() =>
  import('./some-dynamic-comp').then((mod) => mod.SomeDynamicComp),
{ ssr: false })

The test that fails:

import React from 'react'
import { render } from '@testing-library/react'

import { SomeComp } from './some-comp'

it('renders without error', () => {
  render(<SomeComp />)
})

When those were removed, the tests passed again on 10.2.0. Leaving them in and pinning next to 10.1.3, things worked again.

Expected Behavior

That I can test react components in jest that utilize next/dynamic.

To Reproduce

Reproducible gist incoming. I need to extract out a simplified example. Hang tight.

Failing example: https://github.com/ballpit/dynamic-10.2-bug/tree/master/components Passing workaround: https://github.com/ballpit/dynamic-10.2-bug/compare/workaround

To run, just clone and run npm run test. Jest is configured to use the following babel config:

{
  "presets": ["next/babel"],
  "plugins": []
}

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 62
  • Comments: 23 (2 by maintainers)

Most upvoted comments

Suffering from same issue. jest-next-dynamic also stopped working with 10.2 update. Workarounds other than downgrading Next.js to 10.1.3 would be appreciated.

Looks like a fix is being developed in https://github.com/vercel/next.js/pull/24751

Thanks you maintainers!

module.exports = (api) => { const isTest = api.env(‘test’); api.cache(true); if (isTest) { return { presets: [‘@babel/preset-env’, ‘@babel/preset-react’, ‘@babel/preset-typescript’],

        env: {
            test: {
                presets: [['@babel/preset-env', { targets: { node: 'current' } }]],
            },
        },
    };
}

return {
    presets: ['next/babel'],
};

}

Great! This workaround worked for me. For a project not using typescript, but using styled-jsx, this is what my config looks like:

// .babelrc.js
module.exports = (api) => {
  const isTest = api.env('test')
  api.cache(true)

  // remove this part when https://github.com/vercel/next.js/issues/24566 is closed
  if (isTest) {
    return {
      presets: ['@babel/preset-env', '@babel/preset-react'],
      plugins: ['styled-jsx/babel'],
      env: {
        test: {
          presets: [['@babel/preset-env', { targets: { node: 'current' } }]]
        }
      }
    }
  }

  return {
    presets: ['next/babel']
  }
}

This appears to be a valid work around until https://github.com/vercel/next.js/pull/24751 is landed.

Hi, for now I’m doing this:

####### jest.setup.js

jest.isolateModules(() => {
  const preloadAll = require('jest-next-dynamic');
  beforeAll(async () => {
    await preloadAll();
  });
});

And always using ssr false:

const ResponsiveImages = dynamic(import('components/ResponsiveImage/ResponsiveImages'), { ssr: false });

Maybe it could help you @bcomnes

Having the same errors from the same line in react-loadable-plugin when trying to run storybook with next@10.2.

I can confirm that this workaround works well. The only think I had to adjust was to extend the @babel/preset-react with a runtime: automatic option, otherwise jest would fail on ReferenceError: React is not defined error.

[
  "@babel/preset-react",
  {
    "runtime": "automatic"
  }
]

it seems the next/dist/build/babel/plugins/react-loadable-plugin.js is causing the issue. I created a separate babel test config which doesn’t include the next/babel preset

Hi, for now I’m doing this:

I tried it out, however this did not solve the problem for me, same error. I had to add the following line to my jest config file to enable a setup file:

setupFilesAfterEnv: ['./jest.setup.js']

And even added the additional babel plugin they recommend:

"plugins": ["babel-plugin-dynamic-import-node"]

Nearly the same issue when using extract-react-intl-messages. Breaks on any file with dynamic imports.

TypeError: /src/components/LanguageSelector/index.tsx: Cannot read property 'pagesDir' of undefined
    at Import (/node_modules/next/dist/build/babel/plugins/react-loadable-plugin.js:25:864)
    at NodePath._call (/node_modules/@babel/core/node_modules/@babel/traverse/lib/path/context.js:55:20)
    at NodePath.call (/node_modules/@babel/core/node_modules/@babel/traverse/lib/path/context.js:42:17)
    at NodePath.visit (/node_modules/@babel/core/node_modules/@babel/traverse/lib/path/context.js:92:31)
    at TraversalContext.visitQueue (/node_modules/@babel/core/node_modules/@babel/traverse/lib/context.js:115:16)
    at TraversalContext.visitSingle (/node_modules/@babel/core/node_modules/@babel/traverse/lib/context.js:84:19)
    at TraversalContext.visit (/node_modules/@babel/core/node_modules/@babel/traverse/lib/context.js:143:19)
    at Function.traverse.node (/node_modules/@babel/core/node_modules/@babel/traverse/lib/index.js:82:17)
    at NodePath.visit (/node_modules/@babel/core/node_modules/@babel/traverse/lib/path/context.js:99:18)
    at TraversalContext.visitQueue (/node_modules/@babel/core/node_modules/@babel/traverse/lib/context.js:115:16)

Cool thank you for the workaround @omariosouto! I will try that.

Ok added a reproducible example:

Failing example: https://github.com/ballpit/dynamic-10.2-bug/tree/master/components Passing workaround: https://github.com/ballpit/dynamic-10.2-bug/compare/workaround

To run, just clone and run npm run test. Jest is configured to use the following babel config:

{
  "presets": ["next/babel"],
  "plugins": []
}