Skip to content

Commit ef1464f

Browse files
fix: apply development|production condition on Vite 6 (#7301)
Co-authored-by: Vladimir Sheremet <sleuths.slews0s@icloud.com>
1 parent 0b404e5 commit ef1464f

File tree

18 files changed

+233
-25
lines changed

18 files changed

+233
-25
lines changed

docs/guide/migration.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ expect(() => {
129129

130130
See PR for more details: [#5876](https://github.com/vitest-dev/vitest/pull/5876).
131131

132+
### `module` condition export is not resolved by default on Vite 6
133+
134+
Vite 6 allows more flexible [`resolve.conditions`](https://vite.dev/config/shared-options#resolve-conditions) options and Vitest configures it to exclude `module` conditional export by default.
135+
132136
### `Custom` Type is Deprecated <Badge type="danger">API</Badge> {#custom-type-is-deprecated}
133137

134138
The `Custom` type is now an alias for the `Test` type. Note that Vitest updated the public types in 2.1 and changed exported names to `RunnerCustomCase` and `RunnerTestCase`:

packages/vitest/src/node/plugins/index.ts

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { VitestOptimizer } from './optimizer'
2020
import { SsrReplacerPlugin } from './ssrReplacer'
2121
import {
2222
deleteDefineConfig,
23+
getDefaultResolveOptions,
2324
hijackVitePluginInject,
2425
resolveFsAllow,
2526
} from './utils'
@@ -73,6 +74,8 @@ export async function VitestPlugin(
7374
open = testConfig.uiBase ?? '/__vitest__/'
7475
}
7576

77+
const resolveOptions = getDefaultResolveOptions()
78+
7679
const config: ViteConfig = {
7780
root: viteConfig.test?.root || options.root,
7881
esbuild:
@@ -86,11 +89,8 @@ export async function VitestPlugin(
8689
legalComments: 'inline',
8790
},
8891
resolve: {
89-
// by default Vite resolves `module` field, which not always a native ESM module
90-
// setting this option can bypass that and fallback to cjs version
91-
mainFields: [],
92+
...resolveOptions,
9293
alias: testConfig.alias,
93-
conditions: ['node'],
9494
},
9595
server: {
9696
...testConfig.api,
@@ -115,12 +115,7 @@ export async function VitestPlugin(
115115
// @ts-ignore Vite 6 compat
116116
environments: {
117117
ssr: {
118-
resolve: {
119-
// by default Vite resolves `module` field, which not always a native ESM module
120-
// setting this option can bypass that and fallback to cjs version
121-
mainFields: [],
122-
conditions: ['node'],
123-
},
118+
resolve: resolveOptions,
124119
},
125120
},
126121
test: {

packages/vitest/src/node/plugins/utils.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type {
66
import type { DepsOptimizationOptions, InlineConfig } from '../types/config'
77
import { dirname } from 'pathe'
88
import { searchForWorkspaceRoot, version as viteVersion } from 'vite'
9+
import * as vite from 'vite'
910
import { rootDir } from '../../paths'
1011
import { VitestCache } from '../cache'
1112

@@ -147,3 +148,23 @@ export function resolveFsAllow(
147148
rootDir,
148149
]
149150
}
151+
152+
export function getDefaultResolveOptions(): vite.ResolveOptions {
153+
return {
154+
// by default Vite resolves `module` field, which is not always a native ESM module
155+
// setting this option can bypass that and fallback to cjs version
156+
mainFields: [],
157+
// same for `module` condition and Vite 5 doesn't even allow excluding it,
158+
// but now it's possible since Vite 6.
159+
conditions: getDefaultServerConditions(),
160+
}
161+
}
162+
163+
function getDefaultServerConditions(): string[] {
164+
const viteMajor = Number(viteVersion.split('.')[0])
165+
if (viteMajor >= 6) {
166+
const conditions: string[] = (vite as any).defaultServerConditions
167+
return conditions.filter(c => c !== 'module')
168+
}
169+
return ['node']
170+
}

packages/vitest/src/node/plugins/workspace.ts

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { VitestOptimizer } from './optimizer'
1616
import { SsrReplacerPlugin } from './ssrReplacer'
1717
import {
1818
deleteDefineConfig,
19+
getDefaultResolveOptions,
1920
hijackVitePluginInject,
2021
resolveFsAllow,
2122
} from './utils'
@@ -92,14 +93,12 @@ export function WorkspaceVitestPlugin(
9293
}
9394
}
9495

96+
const resolveOptions = getDefaultResolveOptions()
9597
const config: ViteConfig = {
9698
root,
9799
resolve: {
98-
// by default Vite resolves `module` field, which not always a native ESM module
99-
// setting this option can bypass that and fallback to cjs version
100-
mainFields: [],
100+
...resolveOptions,
101101
alias: testConfig.alias,
102-
conditions: ['node'],
103102
},
104103
esbuild: viteConfig.esbuild === false
105104
? false
@@ -130,12 +129,7 @@ export function WorkspaceVitestPlugin(
130129
// @ts-ignore Vite 6 compat
131130
environments: {
132131
ssr: {
133-
resolve: {
134-
// by default Vite resolves `module` field, which not always a native ESM module
135-
// setting this option can bypass that and fallback to cjs version
136-
mainFields: [],
137-
conditions: ['node'],
138-
},
132+
resolve: resolveOptions,
139133
},
140134
},
141135
test: {

packages/vitest/src/node/pool.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type { TestSpecification } from './spec'
55
import type { BuiltinPool, Pool } from './types/pool-options'
66
import { isatty } from 'node:tty'
77
import mm from 'micromatch'
8+
import { version as viteVersion } from 'vite'
89
import { isWindows } from '../utils/env'
910
import { createForksPool } from './pools/forks'
1011
import { createThreadsPool } from './pools/threads'
@@ -91,11 +92,14 @@ export function createPool(ctx: Vitest): ProcessPool {
9192

9293
// in addition to resolve.conditions Vite also adds production/development,
9394
// see: https://github.com/vitejs/vite/blob/af2aa09575229462635b7cbb6d248ca853057ba2/packages/vite/src/node/plugins/resolve.ts#L1056-L1080
94-
const potentialConditions = new Set([
95-
'production',
96-
'development',
97-
...ctx.vite.config.resolve.conditions,
98-
])
95+
const viteMajor = Number(viteVersion.split('.')[0])
96+
const potentialConditions = new Set(viteMajor >= 6
97+
? (ctx.vite.config.ssr.resolve?.conditions ?? [])
98+
: [
99+
'production',
100+
'development',
101+
...ctx.vite.config.resolve.conditions,
102+
])
99103
const conditions = [...potentialConditions]
100104
.filter((condition) => {
101105
if (condition === 'production') {
@@ -106,6 +110,12 @@ export function createPool(ctx: Vitest): ProcessPool {
106110
}
107111
return true
108112
})
113+
.map((condition) => {
114+
if (viteMajor >= 6 && condition === 'development|production') {
115+
return ctx.vite.config.isProduction ? 'production' : 'development'
116+
}
117+
return condition
118+
})
109119
.flatMap(c => ['--conditions', c])
110120

111121
// Instead of passing whole process.execArgv to the workers, pick allowed options.

pnpm-lock.yaml

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default false
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"name": "@vitest/test-dep-conditions-indirect",
3+
"type": "module",
4+
"private": true,
5+
"exports": {
6+
"./custom": {
7+
"custom": "./true.js",
8+
"default": "./false.js"
9+
},
10+
"./module": {
11+
"module": "./true.js",
12+
"default": "./false.js"
13+
},
14+
"./node": {
15+
"node": "./true.js",
16+
"default": "./false.js"
17+
},
18+
"./development": {
19+
"development": "./true.js",
20+
"default": "./false.js"
21+
},
22+
"./production": {
23+
"production": "./true.js",
24+
"default": "./false.js"
25+
}
26+
}
27+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default true
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default false

0 commit comments

Comments
 (0)