Skip to content

Commit b6c4a6c

Browse files
committed
Revert "feat!: remove transformMode option"
This reverts commit 7983d53.
1 parent 7983d53 commit b6c4a6c

File tree

23 files changed

+121
-152
lines changed

23 files changed

+121
-152
lines changed

docs/config/index.md

+36
Original file line numberDiff line numberDiff line change
@@ -1117,6 +1117,42 @@ Will call [`vi.unstubAllEnvs`](/api/vi#vi-unstuballenvs) before each test.
11171117

11181118
Will call [`vi.unstubAllGlobals`](/api/vi#vi-unstuballglobals) before each test.
11191119

1120+
### transformMode
1121+
1122+
- **Type:** `{ web?, ssr? }`
1123+
1124+
Determine the transform method of modules
1125+
1126+
#### transformMode.ssr
1127+
1128+
- **Type:** `RegExp[]`
1129+
- **Default:** `[/\.([cm]?[jt]sx?|json)$/]`
1130+
1131+
Use SSR transform pipeline for the specified files.<br>
1132+
Vite plugins will receive `ssr: true` flag when processing those files.
1133+
1134+
#### transformMode&#46;web
1135+
1136+
- **Type:** `RegExp[]`
1137+
- **Default:** *modules other than those specified in `transformMode.ssr`*
1138+
1139+
First do a normal transform pipeline (targeting browser), then do a SSR rewrite to run the code in Node.<br>
1140+
Vite plugins will receive `ssr: false` flag when processing those files.
1141+
1142+
When you use JSX as component models other than React (e.g. Vue JSX or SolidJS), you might want to config as following to make `.tsx` / `.jsx` transformed as client-side components:
1143+
1144+
```ts
1145+
import { defineConfig } from 'vitest/config'
1146+
1147+
export default defineConfig({
1148+
test: {
1149+
transformMode: {
1150+
web: [/\.[jt]sx$/],
1151+
},
1152+
},
1153+
})
1154+
```
1155+
11201156
### snapshotFormat<NonProjectOption />
11211157

11221158
- **Type:** `PrettyFormatOptions`

examples/solid/vite.config.mjs

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import solid from 'vite-plugin-solid'
77
export default defineConfig({
88
test: {
99
environment: 'jsdom',
10+
transformMode: {
11+
web: [/.[jt]sx?/],
12+
},
1013
threads: false,
1114
isolate: false,
1215
},

examples/vue-jsx/vite.config.ts

+3
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,8 @@ export default defineConfig({
77
test: {
88
globals: true,
99
environment: 'jsdom',
10+
transformMode: {
11+
web: [/.[tj]sx$/],
12+
},
1013
},
1114
})

packages/vitest/src/integrations/env/edge-runtime.ts

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { populateGlobal } from './utils'
44

55
export default <Environment>({
66
name: 'edge-runtime',
7-
transformMode: 'ssr',
87
async setup(global) {
98
const { EdgeVM } = await importModule('@edge-runtime/vm') as typeof import('@edge-runtime/vm')
109
const vm = new EdgeVM({

packages/vitest/src/integrations/env/happy-dom.ts

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { populateGlobal } from './utils'
44

55
export default <Environment>({
66
name: 'happy-dom',
7-
transformMode: 'web',
87
async setup(global) {
98
// happy-dom v3 introduced a breaking change to Window, but
109
// provides GlobalWindow as a way to use previous behaviour
+1-21
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import type { BuiltinEnvironment, VitestEnvironment } from '../../types/config'
2-
import type { VitestExecutor } from '../../node'
3-
import type { Environment } from '../../types'
1+
import type { VitestEnvironment } from '../../types/config'
42
import node from './node'
53
import jsdom from './jsdom'
64
import happy from './happy-dom'
@@ -21,28 +19,10 @@ export const envPackageNames: Record<Exclude<keyof typeof environments, 'node'>,
2119
'edge-runtime': '@edge-runtime/vm',
2220
}
2321

24-
function isBuiltinEnvironment(env: VitestEnvironment): env is BuiltinEnvironment {
25-
return env in environments
26-
}
27-
2822
export function getEnvPackageName(env: VitestEnvironment) {
2923
if (env === 'node')
3024
return null
3125
if (env in envPackageNames)
3226
return (envPackageNames as any)[env]
3327
return `vitest-environment-${env}`
3428
}
35-
36-
export async function loadEnvironment(name: VitestEnvironment, executor: VitestExecutor): Promise<Environment> {
37-
if (isBuiltinEnvironment(name))
38-
return environments[name]
39-
const packageId = (name[0] === '.' || name[0] === '/') ? name : `vitest-environment-${name}`
40-
const pkg = await executor.executeId(packageId)
41-
if (!pkg || !pkg.default || typeof pkg.default !== 'object' || typeof pkg.default.setup !== 'function') {
42-
throw new Error(
43-
`Environment "${name}" is not a valid environment. `
44-
+ `Package "vitest-environment-${name}" should have default export with "setup" method.`,
45-
)
46-
}
47-
return pkg.default
48-
}

packages/vitest/src/integrations/env/jsdom.ts

-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ function catchWindowErrors(window: Window) {
2828

2929
export default <Environment>({
3030
name: 'jsdom',
31-
transformMode: 'web',
3231
async setup(global, { jsdom = {} }) {
3332
const {
3433
CookieJar,

packages/vitest/src/integrations/env/node.ts

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import type { Environment } from '../../types'
33

44
export default <Environment>({
55
name: 'node',
6-
transformMode: 'ssr',
76
async setup(global) {
87
global.console.Console = Console
98
return {

packages/vitest/src/node/pools/rpc.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { RawSourceMap } from 'vite-node'
22
import type { RuntimeRPC } from '../../types'
3+
import { getEnvironmentTransformMode } from '../../utils/base'
34
import type { WorkspaceProject } from '../workspace'
45

56
export function createMethodsRPC(project: WorkspaceProject): RuntimeRPC {
@@ -24,10 +25,12 @@ export function createMethodsRPC(project: WorkspaceProject): RuntimeRPC {
2425
const r = await project.vitenode.transformRequest(id)
2526
return r?.map as RawSourceMap | undefined
2627
},
27-
fetch(id, transformMode) {
28+
fetch(id, environment) {
29+
const transformMode = getEnvironmentTransformMode(project.config, environment)
2830
return project.vitenode.fetchModule(id, transformMode)
2931
},
30-
resolveId(id, importer, transformMode) {
32+
resolveId(id, importer, environment) {
33+
const transformMode = getEnvironmentTransformMode(project.config, environment)
3134
return project.vitenode.resolveId(id, importer, transformMode)
3235
},
3336
onPathsCollected(paths) {

packages/vitest/src/runtime/child.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { rpcDone } from './rpc'
1010
import { setupInspect } from './inspector'
1111

1212
function init(ctx: ChildContext) {
13-
const { config, environment } = ctx
13+
const { config } = ctx
1414

1515
process.env.VITEST_WORKER_ID = '1'
1616
process.env.VITEST_POOL_ID = '1'
@@ -21,7 +21,7 @@ function init(ctx: ChildContext) {
2121
})
2222

2323
// @ts-expect-error untyped global
24-
globalThis.__vitest_environment__ = environment.name
24+
globalThis.__vitest_environment__ = config.environment
2525
// @ts-expect-error I know what I am doing :P
2626
globalThis.__vitest_worker__ = {
2727
ctx,
@@ -76,8 +76,8 @@ export async function run(ctx: ChildContext) {
7676

7777
try {
7878
init(ctx)
79-
const { run, executor, environment } = await startViteNode(ctx)
80-
await run(ctx.files, ctx.config, { ...ctx.environment, environment }, executor)
79+
const { run, executor } = await startViteNode(ctx)
80+
await run(ctx.files, ctx.config, ctx.environment, executor)
8181
await rpcDone()
8282
}
8383
finally {

packages/vitest/src/runtime/entry.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { performance } from 'node:perf_hooks'
22
import type { VitestRunner, VitestRunnerConstructor } from '@vitest/runner'
33
import { startTests } from '@vitest/runner'
44
import { resolve } from 'pathe'
5-
import type { ResolvedConfig, ResolvedTestEnvironment } from '../types'
5+
import type { ContextTestEnvironment, ResolvedConfig } from '../types'
66
import { getWorkerState, resetModules } from '../utils'
77
import { vi } from '../integrations/vi'
88
import { distDir } from '../paths'
@@ -89,7 +89,7 @@ async function getTestRunner(config: ResolvedConfig, executor: VitestExecutor):
8989
}
9090

9191
// browser shouldn't call this!
92-
export async function run(files: string[], config: ResolvedConfig, environment: ResolvedTestEnvironment, executor: VitestExecutor): Promise<void> {
92+
export async function run(files: string[], config: ResolvedConfig, environment: ContextTestEnvironment, executor: VitestExecutor): Promise<void> {
9393
const workerState = getWorkerState()
9494

9595
await setupGlobalEnv(config)
@@ -104,11 +104,11 @@ export async function run(files: string[], config: ResolvedConfig, environment:
104104
workerState.durations.prepare = performance.now() - workerState.durations.prepare
105105

106106
// @ts-expect-error untyped global
107-
globalThis.__vitest_environment__ = environment.name
107+
globalThis.__vitest_environment__ = environment
108108

109109
workerState.durations.environment = performance.now()
110110

111-
await withEnv(environment, environment.options || config.environmentOptions || {}, async () => {
111+
await withEnv(environment.name, environment.options || config.environmentOptions || {}, executor, async () => {
112112
workerState.durations.environment = performance.now() - workerState.durations.environment
113113

114114
for (const file of files) {

packages/vitest/src/runtime/execute.ts

+5-12
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ import { normalize, relative, resolve } from 'pathe'
66
import { processError } from '@vitest/runner/utils'
77
import type { MockMap } from '../types/mocker'
88
import { getCurrentEnvironment, getWorkerState } from '../utils/global'
9-
import type { ContextRPC, Environment, ResolvedConfig, ResolvedTestEnvironment } from '../types'
9+
import type { ContextRPC, ContextTestEnvironment, ResolvedConfig } from '../types'
1010
import { distDir } from '../paths'
11-
import { loadEnvironment } from '../integrations/env'
1211
import { VitestMocker } from './mocker'
1312
import { rpc } from './rpc'
1413

@@ -26,9 +25,8 @@ export async function createVitestExecutor(options: ExecuteOptions) {
2625
}
2726

2827
let _viteNode: {
29-
run: (files: string[], config: ResolvedConfig, environment: ResolvedTestEnvironment, executor: VitestExecutor) => Promise<void>
28+
run: (files: string[], config: ResolvedConfig, environment: ContextTestEnvironment, executor: VitestExecutor) => Promise<void>
3029
executor: VitestExecutor
31-
environment: Environment
3230
}
3331

3432
export const moduleCache = new ModuleCacheMap()
@@ -63,14 +61,12 @@ export async function startViteNode(ctx: ContextRPC) {
6361
process.on('uncaughtException', e => catchError(e, 'Uncaught Exception'))
6462
process.on('unhandledRejection', e => catchError(e, 'Unhandled Rejection'))
6563

66-
let transformMode: 'ssr' | 'web' = 'ssr'
67-
6864
const executor = await createVitestExecutor({
6965
fetchModule(id) {
70-
return rpc().fetch(id, transformMode)
66+
return rpc().fetch(id, ctx.environment.name)
7167
},
7268
resolveId(id, importer) {
73-
return rpc().resolveId(id, importer, transformMode)
69+
return rpc().resolveId(id, importer, ctx.environment.name)
7470
},
7571
moduleCache,
7672
mockMap,
@@ -80,12 +76,9 @@ export async function startViteNode(ctx: ContextRPC) {
8076
base: config.base,
8177
})
8278

83-
const environment = await loadEnvironment(ctx.environment.name, executor)
84-
transformMode = environment.transformMode ?? 'ssr'
85-
8679
const { run } = await import(pathToFileURL(resolve(distDir, 'entry.js')).href)
8780

88-
_viteNode = { run, executor, environment }
81+
_viteNode = { run, executor }
8982

9083
return _viteNode
9184
}

packages/vitest/src/runtime/setup.node.ts

+21-6
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@ import { createRequire } from 'node:module'
22
import { isatty } from 'node:tty'
33
import { installSourcemapsSupport } from 'vite-node/source-map'
44
import { createColors, setupColors } from '@vitest/utils'
5-
import type { EnvironmentOptions, ResolvedConfig, ResolvedTestEnvironment } from '../types'
5+
import { environments } from '../integrations/env'
6+
import type { Environment, ResolvedConfig } from '../types'
67
import { VitestSnapshotEnvironment } from '../integrations/snapshot/environments/node'
78
import { getSafeTimers, getWorkerState } from '../utils'
89
import * as VitestIndex from '../index'
910
import { RealDate } from '../integrations/mock/date'
1011
import { expect } from '../integrations/chai'
1112
import { rpc } from './rpc'
1213
import { setupCommonEnv } from './setup.common'
14+
import type { VitestExecutor } from './execute'
1315

1416
// this should only be used in Node
1517
let globalSetup = false
@@ -155,17 +157,30 @@ export async function setupConsoleLogSpy() {
155157
})
156158
}
157159

160+
async function loadEnvironment(name: string, executor: VitestExecutor) {
161+
const pkg = await executor.executeId(`vitest-environment-${name}`)
162+
if (!pkg || !pkg.default || typeof pkg.default !== 'object' || typeof pkg.default.setup !== 'function') {
163+
throw new Error(
164+
`Environment "${name}" is not a valid environment. `
165+
+ `Package "vitest-environment-${name}" should have default export with "setup" method.`,
166+
)
167+
}
168+
return pkg.default
169+
}
170+
158171
export async function withEnv(
159-
{ environment, name }: ResolvedTestEnvironment,
160-
options: EnvironmentOptions,
172+
name: ResolvedConfig['environment'],
173+
options: ResolvedConfig['environmentOptions'],
174+
executor: VitestExecutor,
161175
fn: () => Promise<void>,
162176
) {
177+
const config: Environment = (environments as any)[name] || await loadEnvironment(name, executor)
163178
// @ts-expect-error untyped global
164-
globalThis.__vitest_environment__ = name
179+
globalThis.__vitest_environment__ = config.name || name
165180
expect.setState({
166-
environment: name,
181+
environment: config.name || name || 'node',
167182
})
168-
const env = await environment.setup(globalThis, options)
183+
const env = await config.setup(globalThis, options)
169184
try {
170185
await fn()
171186
}

packages/vitest/src/runtime/worker.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ function init(ctx: WorkerContext) {
2424
})
2525

2626
// @ts-expect-error untyped global
27-
globalThis.__vitest_environment__ = config.environment.name
27+
globalThis.__vitest_environment__ = config.environment
2828
// @ts-expect-error I know what I am doing :P
2929
globalThis.__vitest_worker__ = {
3030
ctx,
@@ -62,8 +62,8 @@ export async function run(ctx: WorkerContext) {
6262

6363
try {
6464
init(ctx)
65-
const { run, executor, environment } = await startViteNode(ctx)
66-
await run(ctx.files, ctx.config, { ...ctx.environment, environment }, executor)
65+
const { run, executor } = await startViteNode(ctx)
66+
await run(ctx.files, ctx.config, ctx.environment, executor)
6767
await rpcDone()
6868
}
6969
finally {

packages/vitest/src/types/config.ts

+21
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,27 @@ export interface InlineConfig {
438438
*/
439439
uiBase?: string
440440

441+
/**
442+
* Determine the transform method of modules
443+
*/
444+
transformMode?: {
445+
/**
446+
* Use SSR transform pipeline for the specified files.
447+
* Vite plugins will receive `ssr: true` flag when processing those files.
448+
*
449+
* @default [/\.([cm]?[jt]sx?|json)$/]
450+
*/
451+
ssr?: RegExp[]
452+
/**
453+
* First do a normal transform pipeline (targeting browser),
454+
* then then do a SSR rewrite to run the code in Node.
455+
* Vite plugins will receive `ssr: false` flag when processing those files.
456+
*
457+
* @default other than `ssr`
458+
*/
459+
web?: RegExp[]
460+
}
461+
441462
/**
442463
* Format options for snapshot testing.
443464
*/

packages/vitest/src/types/general.ts

-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ export interface EnvironmentReturn {
2323

2424
export interface Environment {
2525
name: string
26-
transformMode?: 'web' | 'ssr'
2726
setup(global: any, options: Record<string, any>): Awaitable<EnvironmentReturn>
2827
}
2928

0 commit comments

Comments
 (0)