vitest-dev / vitest

Next generation testing framework powered by Vite.
https://vitest.dev
MIT License
13.05k stars 1.17k forks source link

Load coverage packages from the same place where Vitest package is located #6542

Closed leduyquang753 closed 1 month ago

leduyquang753 commented 1 month ago

Clear and concise description of the problem

Currently, when Vitest is run with root set to elsewhere, or when it is run as a global package, the target project has to have the desired coverage package be installed, or this error occurs:

Error: Failed to load url @vitest/coverage-v8 (resolved id: @vitest/coverage-v8). Does the file exist?
 ❯ loadAndTransform ../vitest/node_modules/vite/dist/node/chunks/dep-DG6Lorbi.js:51857:17

Notably, Vitest doesn't prompt to install such coverage package in this case.

This causes difficulties when trying to make use of Vitest as a global tool or for testing external projects.

Suggested solution

Try to load such coverage packages from the same place where the Vitest package is installed, which is either the global or the current directory's node_modules folder, instead of the target project's.

Alternative

No response

Additional context

No response

Validations

AriPerkkio commented 1 month ago

Please use the bug report template for issues that are clearly bugs.

github-actions[bot] commented 1 month ago

Hello @leduyquang753. Please provide a minimal reproduction using a GitHub repository or StackBlitz (you can also use examples). Issues marked with needs reproduction will be closed if they have no activity within 3 days.

leduyquang753 commented 1 month ago

Reproduction steps:

  1. Install vitest and @vitest/coverage-v8 into directory A.
  2. Write this file as bug.spec.ts in directory B:
    import {test} from "vitest";
    test("Test", () => {});
  3. Run npx vitest run --root <Directory B> --coverage from directory A.
AriPerkkio commented 1 month ago
  1. Run npx vitest run --root --coverage from directory A.

But that's not using Vitest that was installed in directory A. The whole step 1 here can be skipped completely and the result should be the same.

Notably, Vitest doesn't prompt to install such coverage package in this case.

When I repeated your steps, it did prompt:

Does it work if you manually install the coverage package globally as well?

leduyquang753 commented 1 month ago

But that's not using Vitest that was installed in directory A. The whole step 1 here can be skipped completely and the result should be the same.

It is using Vitest in directory A, otherwise npm would prompt me this:

Need to install the following packages:
vitest@2.1.1
Ok to proceed? (y)

When I repeated your steps, it did prompt:

It appears your setup has directory B as a subdirectory of directory A; it does also work on my machine. So it seems the issue only comes up when the two directories are totally separate.

To make sure here is a bash script that performs the reproduction steps I listed above: reproduction.txt

Does it work if you manually install the coverage package globally as well?

It doesn't, that was in fact what initially uncovered this issue.

AriPerkkio commented 1 month ago

from directory A.

Oh sorry, I missed this part. Yes, it should be using the Vitest from that directory then.

Feel free to debug this further. The loading happens around here:

https://github.com/vitest-dev/vitest/blob/2a50464d58e98f58fed513971a570a952081bfef/packages/vitest/src/integrations/coverage.ts#L34

AriPerkkio commented 1 month ago

So in this case you have:

├── vitest
│   ├── package-lock.json
│   └── package.json.    # Installs vitest and other dependencies that are loaded via Vite during runtime
└── tests
    └── bug.spec.ts

And now you are running cd vitest; npx vitest --root ../tests. This will set your Vite's root there.

In this case you should be using --dir ../tests instead. That will keep your Vite server's root in the current working directory where you run the command, and picks up the tests from desired directory.