mirror of
https://github.com/vitest-dev/vitest.git
synced 2026-02-01 17:36:51 +00:00
fix: apply development|production condition on Vite 6 (#7301)
Co-authored-by: Vladimir Sheremet <sleuths.slews0s@icloud.com>
This commit is contained in:
parent
0b404e567b
commit
ef1464fc7b
@ -129,6 +129,10 @@ expect(() => {
|
||||
|
||||
See PR for more details: [#5876](https://github.com/vitest-dev/vitest/pull/5876).
|
||||
|
||||
### `module` condition export is not resolved by default on Vite 6
|
||||
|
||||
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.
|
||||
|
||||
### `Custom` Type is Deprecated <Badge type="danger">API</Badge> {#custom-type-is-deprecated}
|
||||
|
||||
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`:
|
||||
|
||||
@ -20,6 +20,7 @@ import { VitestOptimizer } from './optimizer'
|
||||
import { SsrReplacerPlugin } from './ssrReplacer'
|
||||
import {
|
||||
deleteDefineConfig,
|
||||
getDefaultResolveOptions,
|
||||
hijackVitePluginInject,
|
||||
resolveFsAllow,
|
||||
} from './utils'
|
||||
@ -73,6 +74,8 @@ export async function VitestPlugin(
|
||||
open = testConfig.uiBase ?? '/__vitest__/'
|
||||
}
|
||||
|
||||
const resolveOptions = getDefaultResolveOptions()
|
||||
|
||||
const config: ViteConfig = {
|
||||
root: viteConfig.test?.root || options.root,
|
||||
esbuild:
|
||||
@ -86,11 +89,8 @@ export async function VitestPlugin(
|
||||
legalComments: 'inline',
|
||||
},
|
||||
resolve: {
|
||||
// by default Vite resolves `module` field, which not always a native ESM module
|
||||
// setting this option can bypass that and fallback to cjs version
|
||||
mainFields: [],
|
||||
...resolveOptions,
|
||||
alias: testConfig.alias,
|
||||
conditions: ['node'],
|
||||
},
|
||||
server: {
|
||||
...testConfig.api,
|
||||
@ -115,12 +115,7 @@ export async function VitestPlugin(
|
||||
// @ts-ignore Vite 6 compat
|
||||
environments: {
|
||||
ssr: {
|
||||
resolve: {
|
||||
// by default Vite resolves `module` field, which not always a native ESM module
|
||||
// setting this option can bypass that and fallback to cjs version
|
||||
mainFields: [],
|
||||
conditions: ['node'],
|
||||
},
|
||||
resolve: resolveOptions,
|
||||
},
|
||||
},
|
||||
test: {
|
||||
|
||||
@ -6,6 +6,7 @@ import type {
|
||||
import type { DepsOptimizationOptions, InlineConfig } from '../types/config'
|
||||
import { dirname } from 'pathe'
|
||||
import { searchForWorkspaceRoot, version as viteVersion } from 'vite'
|
||||
import * as vite from 'vite'
|
||||
import { rootDir } from '../../paths'
|
||||
import { VitestCache } from '../cache'
|
||||
|
||||
@ -147,3 +148,23 @@ export function resolveFsAllow(
|
||||
rootDir,
|
||||
]
|
||||
}
|
||||
|
||||
export function getDefaultResolveOptions(): vite.ResolveOptions {
|
||||
return {
|
||||
// by default Vite resolves `module` field, which is not always a native ESM module
|
||||
// setting this option can bypass that and fallback to cjs version
|
||||
mainFields: [],
|
||||
// same for `module` condition and Vite 5 doesn't even allow excluding it,
|
||||
// but now it's possible since Vite 6.
|
||||
conditions: getDefaultServerConditions(),
|
||||
}
|
||||
}
|
||||
|
||||
function getDefaultServerConditions(): string[] {
|
||||
const viteMajor = Number(viteVersion.split('.')[0])
|
||||
if (viteMajor >= 6) {
|
||||
const conditions: string[] = (vite as any).defaultServerConditions
|
||||
return conditions.filter(c => c !== 'module')
|
||||
}
|
||||
return ['node']
|
||||
}
|
||||
|
||||
@ -16,6 +16,7 @@ import { VitestOptimizer } from './optimizer'
|
||||
import { SsrReplacerPlugin } from './ssrReplacer'
|
||||
import {
|
||||
deleteDefineConfig,
|
||||
getDefaultResolveOptions,
|
||||
hijackVitePluginInject,
|
||||
resolveFsAllow,
|
||||
} from './utils'
|
||||
@ -92,14 +93,12 @@ export function WorkspaceVitestPlugin(
|
||||
}
|
||||
}
|
||||
|
||||
const resolveOptions = getDefaultResolveOptions()
|
||||
const config: ViteConfig = {
|
||||
root,
|
||||
resolve: {
|
||||
// by default Vite resolves `module` field, which not always a native ESM module
|
||||
// setting this option can bypass that and fallback to cjs version
|
||||
mainFields: [],
|
||||
...resolveOptions,
|
||||
alias: testConfig.alias,
|
||||
conditions: ['node'],
|
||||
},
|
||||
esbuild: viteConfig.esbuild === false
|
||||
? false
|
||||
@ -130,12 +129,7 @@ export function WorkspaceVitestPlugin(
|
||||
// @ts-ignore Vite 6 compat
|
||||
environments: {
|
||||
ssr: {
|
||||
resolve: {
|
||||
// by default Vite resolves `module` field, which not always a native ESM module
|
||||
// setting this option can bypass that and fallback to cjs version
|
||||
mainFields: [],
|
||||
conditions: ['node'],
|
||||
},
|
||||
resolve: resolveOptions,
|
||||
},
|
||||
},
|
||||
test: {
|
||||
|
||||
@ -5,6 +5,7 @@ import type { TestSpecification } from './spec'
|
||||
import type { BuiltinPool, Pool } from './types/pool-options'
|
||||
import { isatty } from 'node:tty'
|
||||
import mm from 'micromatch'
|
||||
import { version as viteVersion } from 'vite'
|
||||
import { isWindows } from '../utils/env'
|
||||
import { createForksPool } from './pools/forks'
|
||||
import { createThreadsPool } from './pools/threads'
|
||||
@ -91,11 +92,14 @@ export function createPool(ctx: Vitest): ProcessPool {
|
||||
|
||||
// in addition to resolve.conditions Vite also adds production/development,
|
||||
// see: https://github.com/vitejs/vite/blob/af2aa09575229462635b7cbb6d248ca853057ba2/packages/vite/src/node/plugins/resolve.ts#L1056-L1080
|
||||
const potentialConditions = new Set([
|
||||
'production',
|
||||
'development',
|
||||
...ctx.vite.config.resolve.conditions,
|
||||
])
|
||||
const viteMajor = Number(viteVersion.split('.')[0])
|
||||
const potentialConditions = new Set(viteMajor >= 6
|
||||
? (ctx.vite.config.ssr.resolve?.conditions ?? [])
|
||||
: [
|
||||
'production',
|
||||
'development',
|
||||
...ctx.vite.config.resolve.conditions,
|
||||
])
|
||||
const conditions = [...potentialConditions]
|
||||
.filter((condition) => {
|
||||
if (condition === 'production') {
|
||||
@ -106,6 +110,12 @@ export function createPool(ctx: Vitest): ProcessPool {
|
||||
}
|
||||
return true
|
||||
})
|
||||
.map((condition) => {
|
||||
if (viteMajor >= 6 && condition === 'development|production') {
|
||||
return ctx.vite.config.isProduction ? 'production' : 'development'
|
||||
}
|
||||
return condition
|
||||
})
|
||||
.flatMap(c => ['--conditions', c])
|
||||
|
||||
// Instead of passing whole process.execArgv to the workers, pick allowed options.
|
||||
|
||||
15
pnpm-lock.yaml
generated
15
pnpm-lock.yaml
generated
@ -1123,6 +1123,9 @@ importers:
|
||||
|
||||
test/config:
|
||||
devDependencies:
|
||||
'@vitest/test-dep-conditions':
|
||||
specifier: file:./deps/test-dep-conditions
|
||||
version: file:test/config/deps/test-dep-conditions
|
||||
tinyexec:
|
||||
specifier: ^0.3.2
|
||||
version: 0.3.2
|
||||
@ -4126,6 +4129,12 @@ packages:
|
||||
'@vitest/test-dep-cjs@file:test/core/deps/dep-cjs':
|
||||
resolution: {directory: test/core/deps/dep-cjs, type: directory}
|
||||
|
||||
'@vitest/test-dep-conditions-indirect@file:test/config/deps/test-dep-conditions-indirect':
|
||||
resolution: {directory: test/config/deps/test-dep-conditions-indirect, type: directory}
|
||||
|
||||
'@vitest/test-dep-conditions@file:test/config/deps/test-dep-conditions':
|
||||
resolution: {directory: test/config/deps/test-dep-conditions, type: directory}
|
||||
|
||||
'@vitest/test-dep1@file:test/core/deps/dep1':
|
||||
resolution: {directory: test/core/deps/dep1, type: directory}
|
||||
|
||||
@ -12719,6 +12728,12 @@ snapshots:
|
||||
|
||||
'@vitest/test-dep-cjs@file:test/core/deps/dep-cjs': {}
|
||||
|
||||
'@vitest/test-dep-conditions-indirect@file:test/config/deps/test-dep-conditions-indirect': {}
|
||||
|
||||
'@vitest/test-dep-conditions@file:test/config/deps/test-dep-conditions':
|
||||
dependencies:
|
||||
'@vitest/test-dep-conditions-indirect': file:test/config/deps/test-dep-conditions-indirect
|
||||
|
||||
'@vitest/test-dep1@file:test/core/deps/dep1': {}
|
||||
|
||||
'@vitest/test-dep2@file:test/core/deps/dep2':
|
||||
|
||||
1
test/config/deps/test-dep-conditions-indirect/false.js
Normal file
1
test/config/deps/test-dep-conditions-indirect/false.js
Normal file
@ -0,0 +1 @@
|
||||
export default false
|
||||
27
test/config/deps/test-dep-conditions-indirect/package.json
Normal file
27
test/config/deps/test-dep-conditions-indirect/package.json
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "@vitest/test-dep-conditions-indirect",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"exports": {
|
||||
"./custom": {
|
||||
"custom": "./true.js",
|
||||
"default": "./false.js"
|
||||
},
|
||||
"./module": {
|
||||
"module": "./true.js",
|
||||
"default": "./false.js"
|
||||
},
|
||||
"./node": {
|
||||
"node": "./true.js",
|
||||
"default": "./false.js"
|
||||
},
|
||||
"./development": {
|
||||
"development": "./true.js",
|
||||
"default": "./false.js"
|
||||
},
|
||||
"./production": {
|
||||
"production": "./true.js",
|
||||
"default": "./false.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
1
test/config/deps/test-dep-conditions-indirect/true.js
Normal file
1
test/config/deps/test-dep-conditions-indirect/true.js
Normal file
@ -0,0 +1 @@
|
||||
export default true
|
||||
1
test/config/deps/test-dep-conditions/false.js
Normal file
1
test/config/deps/test-dep-conditions/false.js
Normal file
@ -0,0 +1 @@
|
||||
export default false
|
||||
13
test/config/deps/test-dep-conditions/indirect.js
Normal file
13
test/config/deps/test-dep-conditions/indirect.js
Normal file
@ -0,0 +1,13 @@
|
||||
import conditionCustom from '@vitest/test-dep-conditions-indirect/custom'
|
||||
import conditionDevelopment from '@vitest/test-dep-conditions-indirect/development'
|
||||
import conditionModule from '@vitest/test-dep-conditions-indirect/module'
|
||||
import conditionNode from '@vitest/test-dep-conditions-indirect/node'
|
||||
import conditionProductioin from '@vitest/test-dep-conditions-indirect/production'
|
||||
|
||||
export default {
|
||||
conditionCustom,
|
||||
conditionModule,
|
||||
conditionNode,
|
||||
conditionDevelopment,
|
||||
conditionProductioin,
|
||||
}
|
||||
1
test/config/deps/test-dep-conditions/inline.js
Normal file
1
test/config/deps/test-dep-conditions/inline.js
Normal file
@ -0,0 +1 @@
|
||||
export default !!import.meta.__IS_INLINE__
|
||||
32
test/config/deps/test-dep-conditions/package.json
Normal file
32
test/config/deps/test-dep-conditions/package.json
Normal file
@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "@vitest/test-dep-conditions",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"exports": {
|
||||
"./custom": {
|
||||
"custom": "./true.js",
|
||||
"default": "./false.js"
|
||||
},
|
||||
"./module": {
|
||||
"module": "./true.js",
|
||||
"default": "./false.js"
|
||||
},
|
||||
"./node": {
|
||||
"node": "./true.js",
|
||||
"default": "./false.js"
|
||||
},
|
||||
"./development": {
|
||||
"development": "./true.js",
|
||||
"default": "./false.js"
|
||||
},
|
||||
"./production": {
|
||||
"production": "./true.js",
|
||||
"default": "./false.js"
|
||||
},
|
||||
"./inline": "./inline.js",
|
||||
"./indirect": "./indirect.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vitest/test-dep-conditions-indirect": "file:../test-dep-conditions-indirect"
|
||||
}
|
||||
}
|
||||
1
test/config/deps/test-dep-conditions/true.js
Normal file
1
test/config/deps/test-dep-conditions/true.js
Normal file
@ -0,0 +1 @@
|
||||
export default true
|
||||
37
test/config/fixtures/conditions/basic.test.js
Normal file
37
test/config/fixtures/conditions/basic.test.js
Normal file
@ -0,0 +1,37 @@
|
||||
import { test, expect } from 'vitest';
|
||||
import conditionCustom from '@vitest/test-dep-conditions/custom';
|
||||
import conditionModule from '@vitest/test-dep-conditions/module';
|
||||
import conditionNode from '@vitest/test-dep-conditions/node';
|
||||
import conditionDevelopment from '@vitest/test-dep-conditions/development';
|
||||
import conditionProduction from '@vitest/test-dep-conditions/production';
|
||||
import inline from '@vitest/test-dep-conditions/inline';
|
||||
import indirect from '@vitest/test-dep-conditions/indirect';
|
||||
|
||||
import { viteVersion } from 'vitest/node'
|
||||
const viteMajor = Number(viteVersion.split('.')[0])
|
||||
|
||||
test('conditions', () => {
|
||||
expect({
|
||||
conditionCustom,
|
||||
conditionModule,
|
||||
conditionNode,
|
||||
conditionDevelopment,
|
||||
conditionProduction,
|
||||
indirect
|
||||
}).toEqual(
|
||||
{
|
||||
conditionCustom: true,
|
||||
"conditionDevelopment": true,
|
||||
"conditionModule": viteMajor <= 5,
|
||||
"conditionNode": true,
|
||||
"conditionProduction": false,
|
||||
"indirect": {
|
||||
conditionCustom: true,
|
||||
"conditionDevelopment": true,
|
||||
"conditionModule": viteMajor <= 5 && inline,
|
||||
"conditionNode": true,
|
||||
"conditionProductioin": false,
|
||||
},
|
||||
}
|
||||
)
|
||||
})
|
||||
15
test/config/fixtures/conditions/vite.config.ts
Normal file
15
test/config/fixtures/conditions/vite.config.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { defineConfig } from "vitest/config"
|
||||
|
||||
export default defineConfig({
|
||||
define: {
|
||||
'import.meta.__IS_INLINE__': 'true',
|
||||
},
|
||||
resolve: {
|
||||
conditions: ['custom'],
|
||||
},
|
||||
ssr: {
|
||||
resolve: {
|
||||
conditions: ['custom'],
|
||||
},
|
||||
}
|
||||
})
|
||||
@ -6,6 +6,7 @@
|
||||
"test": "vitest --typecheck.enabled"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitest/test-dep-conditions": "file:./deps/test-dep-conditions",
|
||||
"tinyexec": "^0.3.2",
|
||||
"vite": "latest",
|
||||
"vitest": "workspace:*"
|
||||
|
||||
@ -53,6 +53,11 @@ test('correctly imports external dependencies with a custom condition', async ()
|
||||
resolve: {
|
||||
conditions: ['custom'],
|
||||
},
|
||||
ssr: {
|
||||
resolve: {
|
||||
conditions: ['custom'],
|
||||
},
|
||||
},
|
||||
define: {
|
||||
TEST_CONDITION: '"custom"',
|
||||
},
|
||||
@ -60,3 +65,37 @@ test('correctly imports external dependencies with a custom condition', async ()
|
||||
|
||||
expect(stderr).toBe('')
|
||||
})
|
||||
|
||||
test('conditions (external)', async () => {
|
||||
const { stderr } = await runVitest({
|
||||
root: 'fixtures/conditions',
|
||||
})
|
||||
|
||||
expect(stderr).toBe('')
|
||||
})
|
||||
|
||||
test('conditions (inline direct)', async () => {
|
||||
const { stderr } = await runVitest({
|
||||
root: 'fixtures/conditions',
|
||||
server: {
|
||||
deps: {
|
||||
inline: ['@vitest/test-dep-conditions'],
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
expect(stderr).toBe('')
|
||||
})
|
||||
|
||||
test('conditions (inline indirect)', async () => {
|
||||
const { stderr } = await runVitest({
|
||||
root: 'fixtures/conditions',
|
||||
server: {
|
||||
deps: {
|
||||
inline: ['@vitest/test-dep-conditions', '@vitest/test-dep-conditions-indirect'],
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
expect(stderr).toBe('')
|
||||
})
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user