Skip to content
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

Jest tests failing when testing components with dynamic import in Next 10.2.0 #24566

Closed
bcomnes opened this issue Apr 28, 2021 · 23 comments · Fixed by #24751
Closed

Jest tests failing when testing components with dynamic import in Next 10.2.0 #24566

bcomnes opened this issue Apr 28, 2021 · 23 comments · Fixed by #24751
Labels
bug Issue was opened via the bug report template.

Comments

@bcomnes
Copy link

bcomnes commented Apr 28, 2021

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": []
}
@bcomnes bcomnes added the bug Issue was opened via the bug report template. label Apr 28, 2021
@bcomnes
Copy link
Author

bcomnes commented Apr 28, 2021

Possibly related to #24281 ?

@bcomnes
Copy link
Author

bcomnes commented Apr 28, 2021

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": []
}

@stscoundrel
Copy link

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.

@pedroct92
Copy link

We have just updated our project and stated to experience the same issue!

Indeed, it seems related to #24281

We are also using jest-next-dynamic which has an issue open too but it seems the issue is directly here.

It would be nice if we could provide a better API for testing and have the behaviour of jest-next-dynamic directly from nextjs.

Let me know if we could help in any way.

@maccman
Copy link

maccman commented May 3, 2021

Experiencing this issue too.

@travisbloom
Copy link

Having the same errors from the same line in react-loadable-plugin when trying to run storybook with [email protected].

@sct
Copy link

sct commented May 4, 2021

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)

@bcomnes
Copy link
Author

bcomnes commented May 4, 2021

Looks like a fix is being developed in #24751

Thanks you maintainers!

@luiznasciment0
Copy link

I'm experiencing this same issue just after update Next.js version to 10.2 and webpack from 4 to 5.

Component:

import dynamic from 'next/dynamic'
import { Icons, IconProps } from './Icon'

export type TIcon = Icons

export const Icon = dynamic<IconProps>(() => import('./Icon'), {
  ssr: false,
})

Jest error:

Test suite failed to run

    /Users/c84794a/Documents/workspace/ecs-web-authorization-front/main/app/components/Icon/index.tsx: 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)
      at Function.traverse.node (node_modules/@babel/traverse/lib/index.js:82:17)

@omariosouto
Copy link
Contributor

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

@bcomnes
Copy link
Author

bcomnes commented May 5, 2021

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

@bcomnes
Copy link
Author

bcomnes commented May 5, 2021

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"]

@luiznasciment0
Copy link

unfortunately it did not solve the problem for me too :( still waiting for a solution
I'll have to skip tests until the problem is solved, if it takes too long I'll have to downgrade versions

@correttojs
Copy link

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

@luiznasciment0
Copy link

is it possible to overwrite this plugin version? at least until a proper solution is provided

I really don’t want to downgrade next version haha

@luiznasciment0
Copy link

@correttojs can you share your configs, please?

@correttojs
Copy link

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'],
    };
}

@bcomnes
Copy link
Author

bcomnes commented May 6, 2021

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 #24751 is landed.

@klapec
Copy link

klapec commented May 7, 2021

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"
  }
]

@binary64
Copy link

binary64 commented May 7, 2021

Not sure if completely related but in [email protected] I get this (it worked fine in [email protected])

 FAIL  src/lib/show-more/ShowMore.spec.tsx
  ● Test suite failed to run

    /home/user/Code/monorepo/libs/ui/src/lib/myform/SettingElementTextBlock.tsx: 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)
      at Function.traverse.node (../../node_modules/@babel/traverse/lib/index.js:82:17)

my .babelrc.js is just

module.exports = {
  presets: [['next/babel']]
}

@bcomnes
Copy link
Author

bcomnes commented May 7, 2021

Not sure if completely related but in [email protected] I get this (it worked fine in [email protected])

Yup, thats the exact error if that component has a dynamic import in it.

@bcomnes
Copy link
Author

bcomnes commented Aug 17, 2021

Just to follow up because people have asked me about this, after #24751 was landed, I was able to revert back to a simple .babelrc

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

and everything worked fine.

@balazsorban44
Copy link
Member

This issue has been automatically locked due to no recent activity. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@vercel vercel locked as resolved and limited conversation to collaborators Jan 27, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Issue was opened via the bug report template.
Projects
None yet
Development

Successfully merging a pull request may close this issue.