mswjs / msw

Industry standard API mocking for JavaScript.
https://mswjs.io
MIT License
15.97k stars 519 forks source link

Vitest tests fail with error "Cannot find package 'graphql' imported" in v2.4.0 #2248

Open am-ma opened 2 months ago

am-ma commented 2 months ago

Prerequisites

Environment check

Node.js version

v20.10.0

Reproduction repository

https://github.com/am-ma/msw2.4.0-examples-for-issue/tree/main/examples/with-vitest

Reproduction steps

  1. Upgrade nsw to v2.4.0
  2. Run tests <- error occurred

Current behavior

All tests fail.

 FAIL  example-jsdom.test.ts [ example-jsdom.test.ts ]
 FAIL  example.test.ts [ example.test.ts ]
Error: Cannot find package 'graphql' imported from {userDir}/msw2.4.0-examples-for-issue/examples/with-vitest/node_modules/msw/lib/core/utils/internal/parseGraphQLRequest.mjs

Expected behavior

Tests succeed without error.

nartc commented 2 months ago

We ran into the same thing here #2247

CAcarSci commented 2 months ago

I have the same issue here. Installing the graphql package npm i graphql solves the error. However, this means that the latest version of MSW does not make the graphql dependency optional.

ghost91- commented 2 months ago

Also happens to us with jest:

  ● Test suite failed to run

    Cannot find module 'graphql' from '../../node_modules/msw/lib/core/utils/internal/parseGraphQLRequest.js'

    Require stack:
      /home/.../node_modules/msw/lib/core/utils/internal/parseGraphQLRequest.js
      /home/.../node_modules/msw/lib/core/handlers/GraphQLHandler.js
      /home/.../node_modules/msw/lib/core/graphql.js
      /home/.../node_modules/msw/lib/core/index.js
THETCR commented 2 months ago

@kettanaito You only added graphql to peerDependenciesMeta and forget to actually add the dependency under peerDependencies.

kettanaito commented 2 months ago

@THETCR, great catch! This, alongside the fix I described here should resolve the issue.

THETCR commented 2 months ago

@kettanaito The correct fix would be as in #2249

kettanaito commented 2 months ago

Merged the peer dependency fix, opened the lazy import fix in #2250. Reviews are welcome. If someone can also try that PR build in their project, please comment if it fixes the issue or not.

kettanaito commented 2 months ago

Released: v2.4.1 🎉

This has been released in v2.4.1!

Make sure to always update to the latest version (npm i msw@latest) to get the newest features and bug fixes.


Predictable release automation by @ossjs/release.

pascalmann commented 2 months ago

Not work for me. grapql was added to devDependencies (so no installed in my repo), but is still imported (lazily), even if I not use it.

kettanaito commented 2 months ago

If it doesn't work for you, please share a reproduction repo below.

jsphstls commented 2 months ago

The issue persists with v2.4.1:

ERROR in ../../node_modules/graphql/index.mjs 60:0-97:42
Module not found: Error: Can't resolve './utilities' in '/home/runner/work/repo/node_modules/graphql'
Did you mean 'index.js'?
BREAKING CHANGE: The request './utilities' failed to resolve only because it was resolved as fully specified
(probably because the origin is strict EcmaScript Module, e. g. a module with javascript mimetype, a '*.mjs' file, or a '*.js' file where the package.json contains '"type": "module"').
The extension in the request is mandatory for it to be fully specified.
Add the extension to the request.
 @ ../../node_modules/msw/lib/core/utils/internal/parseGraphQLRequest.mjs 15:26-43
 @ ../../node_modules/msw/lib/core/handlers/GraphQLHandler.mjs 9:0-12:51 28:25-42 62:14-33
 @ ../../node_modules/msw/lib/core/index.mjs 7:0-63 17:0-30:2

EDIT: I am using webpack.

kettanaito commented 2 months ago

@jsphstls, reproduction repo, please. That looks like an error originating from the graphql package itself. See if there's an issue about it reported in the graphql-js repo.

NullVoxPopuli commented 2 months ago

webpack runs in to this too -- I think webpack is incorrect here, because it tries to resolve everything, and doesn't understand that some modules deliberately might not be available

nareshbhatia commented 2 months ago

@kettanaito, here's a reproduction repo with next.js. All I did was create-next-app and then installed msw.

https://github.com/nareshbhatia/msw-issue

If we run npm run build, we get this error:

$ npm run build

> msw-issue@0.1.0 build
> next build

  ▲ Next.js 14.2.7

   Creating an optimized production build ...
Failed to compile.

./node_modules/msw/lib/core/utils/internal/parseGraphQLRequest.mjs
Module not found: Can't resolve 'graphql'

https://nextjs.org/docs/messages/module-not-found

Import trace for requested module:
./node_modules/msw/lib/core/handlers/GraphQLHandler.mjs
./node_modules/msw/lib/core/index.mjs
./src/mocks/handlers.js
./src/mocks/browser.js
./src/providers/useMockServiceWorker.ts
./src/providers/AppProvider.tsx

> Build failed because of webpack errors
kettanaito commented 2 months ago

@nareshbhatia, thanks! Can you try the latest MSW version please?

nareshbhatia commented 2 months ago

Hi @kettanaito, tried with msw 2.4.2. Still have the same issue.

CleanShot 2024-09-04 at 15 54 18@2x

kettanaito commented 2 months ago

I suspect this is webpack's magic behavior in regards to dynamic imports. It looks like webpack treats them as a splitting point by default, trying to generate a chunk for import('graphql'), and since importing it fails, you receive the error.

There are different webpack modes to treat dynamic imports. It looks like we need to set /* webpackMode: "eager" */ in the dynamic import to get the regular behavior:

Generates no extra chunk. All modules are included in the current chunk and no additional network requests are made. A Promise is still returned but is already resolved. In contrast to a static import, the module isn't executed until the call to import() is made.

kettanaito commented 2 months ago

Opened a fix at https://github.com/mswjs/msw/pull/2265. Can confirm this fixes the Next.js/webpack builds as reported in https://github.com/mswjs/msw/issues/2248#issuecomment-2322989864.

Went with using the /* webpackIgnore: true */ special comment as suggested on Twitter to make webpack ignore this dynamic import entirely.

kettanaito commented 2 months ago

Released: v2.4.3 🎉

This has been released in v2.4.3!

Make sure to always update to the latest version (npm i msw@latest) to get the newest features and bug fixes.


Predictable release automation by @ossjs/release.

nareshbhatia commented 2 months ago

Thank you, @kettanaito. It works now.

kettanaito commented 1 month ago

I'm reopening this because the solution hasn't been found yet.

This expects GraphQL to be a static import, while the current issue needs it as a dynamic import. Neither work with optional dependencies, and then you add tools like webpack on top that handle dynamic imports in a custom way altogether.

Optional peer dependencies is a mess in JavaScript, and I'm open to suggestions at this point.