Clear and concise description of the problem
Currently Vitest lists vite as a full dependency using:
"vite": "^3.1.0 || ^4.0.0 || ^5.0.0-0",
In my project which uses Vite 4.4.9:
If I then run yarn add vitest, yarn will somewhat unhelpfully install both:
vite v5 and vite v4:
"vite@npm:^3.0.0 || ^4.0.0, vite@npm:^4.4.9":
version: 4.4.9
"vite@npm:^3.1.0 || ^4.0.0 || ^5.0.0-0":
version: 5.0.0-beta.2
The fact that it doesn't see that 4.4.9 satisfies the new condition and just re-use the existing version of vite is annoying, but it winds up causing issues type-checking the vite configuration because there is a type mismatch and two versions of vite are used. The plugins (which use vite as a peer dependency) are using vite 4 types, and "vitest/config" is using the vite 5 types:
Suggested solution
If vitest's vite dependency was listed as a peerDependency, then it would always use the version of vite that is referenced in the project's package.json file and resolutions would not be required to align the two versions.
In terms of potential disadvantages, using vitest would now also require explicitly installing vite. For many users, vite is already installed as a devDependency and no extra work is required. There may be some usage of vitest in projects that don't use vite to build, and for those consumers, this would be a breaking change as it would require adding both vitest and vite under devDependencies. This could be mitigated by shipping vite as both a dependency and peerDependency, but then users would occasionally have two versions of vite installed in node_modules if the version mismatched (currently the case today as well), but only one consistent version would be used (better than today's case).
I'm also not sure what the expected behavior is when doing something like using vitest at the root of a monorepo and specifying a vitest.workspace.ts to find and run tests in different packages. Each of those packages could have their own vite version. With the current behavior, a single version of vite is used for all the different packages, but that version is somewhat opaque to the user and hidden in the lock-file. If vite was a peerDependency then the behavior would be essentially identical, but the version of vite used would be enforced and controlled by the vite dependency at the root level, and would be more transparent to the user.
Generally, I feel like this behavior will be less surprising to users as I would venture to guess that if you polled consumers, they would expect vitest to already be using the same version of vite that is installed in the project, and the fact that they don't necessarily match has the potential for a number of headaches as to why your test behavior doesn't match your build behavior.
Alternative
You can work around the issues by manually massaging the lock file like:
"vite@npm:^3.0.0 || ^4.0.0, vite@npm:^4.4.9, vite@npm:^3.1.0 || ^4.0.0 || ^5.0.0-0":
version: 4.4.9
But if you use a tool like renovate to do periodic lock file maintenance, this will get blown away each time it does so.
A more resilient workaround is to use a resolution:
"resolutions": {
"vite": "^4.4.9"
}
Additional context
No response
Validations
Clear and concise description of the problem
Currently Vitest lists vite as a full dependency using:
In my project which uses Vite 4.4.9:
If I then run
yarn add vitest, yarn will somewhat unhelpfully install both:vite v5 and vite v4:
The fact that it doesn't see that
4.4.9satisfies the new condition and just re-use the existing version of vite is annoying, but it winds up causing issues type-checking the vite configuration because there is a type mismatch and two versions of vite are used. The plugins (which use vite as a peer dependency) are using vite 4 types, and"vitest/config"is using the vite 5 types:Suggested solution
If vitest's vite dependency was listed as a
peerDependency, then it would always use the version of vite that is referenced in the project'spackage.jsonfile and resolutions would not be required to align the two versions.In terms of potential disadvantages, using vitest would now also require explicitly installing vite. For many users, vite is already installed as a devDependency and no extra work is required. There may be some usage of vitest in projects that don't use vite to build, and for those consumers, this would be a breaking change as it would require adding both vitest and vite under devDependencies. This could be mitigated by shipping vite as both a
dependencyandpeerDependency, but then users would occasionally have two versions of vite installed innode_modulesif the version mismatched (currently the case today as well), but only one consistent version would be used (better than today's case).I'm also not sure what the expected behavior is when doing something like using vitest at the root of a monorepo and specifying a vitest.workspace.ts to find and run tests in different packages. Each of those packages could have their own vite version. With the current behavior, a single version of vite is used for all the different packages, but that version is somewhat opaque to the user and hidden in the lock-file. If vite was a peerDependency then the behavior would be essentially identical, but the version of vite used would be enforced and controlled by the vite dependency at the root level, and would be more transparent to the user.
Generally, I feel like this behavior will be less surprising to users as I would venture to guess that if you polled consumers, they would expect vitest to already be using the same version of vite that is installed in the project, and the fact that they don't necessarily match has the potential for a number of headaches as to why your test behavior doesn't match your build behavior.
Alternative
You can work around the issues by manually massaging the lock file like:
But if you use a tool like renovate to do periodic lock file maintenance, this will get blown away each time it does so.
A more resilient workaround is to use a resolution:
Additional context
No response
Validations