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

instanceof checks fail when using peerDeps? #5601

Closed
6 tasks done
skrivle opened this issue Apr 23, 2024 · 5 comments
Closed
6 tasks done

instanceof checks fail when using peerDeps? #5601

skrivle opened this issue Apr 23, 2024 · 5 comments

Comments

@skrivle
Copy link

skrivle commented Apr 23, 2024

Describe the bug

Hi there!

First of all, thank you for all the hard work on vitest! Very much appreciated 🙏 !

When upgrading from 1.4.0 to 1.5.0. we are seeing some of our tests fail.

When debugging we noticed this seems to be related with a failing instanceof check.

More specifically, we have an Apollo GraphQL server and we are relying on instanceof to verify whether an error is an instance of GraphQLError in some places. With 1.5.0 error instanceof GraphQLError fails whereas with 1.4.0 this succeeds.

In this specific case the package @apollo/server is throwing the GraphQLError instance. Apollo server imports GraphQLError from the graphql package on which it has a peerDependency. Our own project then also specifies a dependency on the graphql packages and imports GraphQLError to do the instanceof check.

It feels like somehow the graphql package gets duplicated during bundling? This might explain why instanceof fails?

To be clear we are not seeing this issue during runtime. Only when running tests with vitest.

Reproduction

I have tried to come up with a minimal reproduction:
github: https://github.com/skrivle/vitest-deps-repro.
stackblitz: https://stackblitz.com/~/github.com/skrivle/vitest-deps-repro

  • run yarn test to see failing unit test
  • run yarn start to see a similar check with node succeed.

I have created a test-package that has a peerDependency on graphql just as apollo/server does in our case. This package then throws a GraphQLError. In app.spec.ts we are then verifying whether the error thrown is an instanceof GraphQLError. This fails in the test. However when running a similar script with node (run yarn start) the check seems to succeed just fine.

❗ In our graphql server project our tests do pass with 1.4.0 but fail with 1.5.0. However with the repro I've made, it seems to also be failing with 1.4.0. This is a bit suspicious. Though, I thought it might already be worth sharing...

System Info

System:
    OS: macOS 14.4.1
    CPU: (10) arm64 Apple M1 Pro
    Memory: 1.23 GB / 32.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.11.1 - /opt/homebrew/opt/nvm/versions/node/v20.11.1/bin/node
    Yarn: 3.3.0 - /opt/homebrew/opt/nvm/versions/node/v20.11.1/bin/yarn
    npm: 10.2.4 - /opt/homebrew/opt/nvm/versions/node/v20.11.1/bin/npm
    pnpm: 9.0.5 - /opt/homebrew/opt/nvm/versions/node/v20.11.1/bin/pnpm
  Browsers:
    Chrome: 124.0.6367.62
    Safari: 17.4.1
  npmPackages:
    @vitest/coverage-v8: 1.5.0 => 1.5.0
    vitest: 1.5.0 => 1.5.0

Used Package Manager

yarn

Validations

@hi-ogawa
Copy link
Contributor

hi-ogawa commented Apr 24, 2024

This seems like yet-another instance of dist/esm/... path issue:

@apollo/server seems like a legitimate esm package https://publint.dev/@apollo/server@4.10.4, but Vitest (vite-node) has been incorrectly treating it as a "bad" package and transforming the entire code and that made @apollo/server to import graphql's module entry https://publint.dev/graphql@16.8.1 which is graphql/index.mjs.

Your source code is always transformed, so both were seeing graphql/index.mjs on Vitest v1.4.0, but after the change #5416, the legitimate @apollo/server are not transformed and it ends up loading graphql/index.js since we rely on Node's behavior there, thus dual package happens.

Actually, I don't know why Vitest/Vite is not reading "main": "index" entry (which they probably mean index.js), but this might be partly because of graphql side's issue or Vite resolution issue.

You can try server.deps.inline: ["@apollo/server"] (like I mentioned in #5555 (comment)) to get back to the previous behavior and that should fix the issue, but potentially there's other issue involved with this.

@skrivle
Copy link
Author

skrivle commented Apr 24, 2024

Hi!

Thanks for the quick response! I've tried using deps.inline and it does work for the repro I have created (adding 'test-package'). Though for our real project it ends up throwing this error at me:

Screenshot 2024-04-24 at 09 54 32

It seems like the graphql package might actually be the one (partially) causing the problem as described here: graphql/graphql-js#4062

@hi-ogawa
Copy link
Contributor

hi-ogawa commented Apr 24, 2024

Hmm, I expected server.deps.inline should be the only factor for your case. Maybe you have other package importing graphql. Can you try something like yarn why graphql?


Also the other thing I was wondering about is rather unusual "main": "index" entry and indeed it looks like this is tripping off Vitest's normal resolution. Patching it to "main": "index.js" seems to make Vitest to import graphql/index.js instead of graphql/index.mjs.

@hi-ogawa
Copy link
Contributor

hi-ogawa commented Apr 24, 2024

One more thing I forgot to mention is that you can force Vitest's resolution using alias.
For example, one idea would be to borrow NodeJs's require by something like:

import { createRequire } from "node:module";
const require = createRequire(import.meta.url);

export default defineConfig({
  test: {
      alias: {
          // or maybe simply __dirname + "/node_modules/graphql/index.js"
          "graphql": require.resolve("graphql"),
      }
  }
});

@skrivle
Copy link
Author

skrivle commented Apr 24, 2024

Ah, yes you're right. I forgot that there were other packages with a peer dependency on graphql. Adding those fixes it.

I can also confirm that the second solution work as well. We might prefer that for now since it seems like that's the package causing the issue.

Thanks again 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants