Skip to content

Commit 9630288

Browse files
committed
feat!: remove transformMode option
1 parent 2deb70a commit 9630288

File tree

23 files changed

+152
-121
lines changed

23 files changed

+152
-121
lines changed

docs/config/index.md

-36
Original file line numberDiff line numberDiff line change
@@ -1117,42 +1117,6 @@ 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-
11561120
### snapshotFormat<NonProjectOption />
11571121

11581122
- **Type:** `PrettyFormatOptions`

examples/solid/vite.config.mjs

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

examples/vue-jsx/vite.config.ts

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

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

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

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

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

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

55
export default <Environment>({
66
name: 'happy-dom',
7+
transformMode: 'web',
78
async setup(global) {
89
// happy-dom v3 introduced a breaking change to Window, but
910
// provides GlobalWindow as a way to use previous behaviour

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

+21-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import type { VitestEnvironment } from '../../types/config'
1+
import type { BuiltinEnvironment, VitestEnvironment } from '../../types/config'
2+
import type { VitestExecutor } from '../../node'
3+
import type { Environment } from '../../types'
24
import node from './node'
35
import jsdom from './jsdom'
46
import happy from './happy-dom'
@@ -19,10 +21,28 @@ export const envPackageNames: Record<Exclude<keyof typeof environments, 'node'>,
1921
'edge-runtime': '@edge-runtime/vm',
2022
}
2123

24+
function isBuiltinEnvironment(env: VitestEnvironment): env is BuiltinEnvironment {
25+
return env in environments
26+
}
27+
2228
export function getEnvPackageName(env: VitestEnvironment) {
2329
if (env === 'node')
2430
return null
2531
if (env in envPackageNames)
2632
return (envPackageNames as any)[env]
2733
return `vitest-environment-${env}`
2834
}
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,6 +28,7 @@ function catchWindowErrors(window: Window) {
2828

2929
export default <Environment>({
3030
name: 'jsdom',
31+
transformMode: 'web',
3132
async setup(global, { jsdom = {} }) {
3233
const {
3334
CookieJar,

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

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

44
export default <Environment>({
55
name: 'node',
6+
transformMode: 'ssr',
67
async setup(global) {
78
global.console.Console = Console
89
return {

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

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

65
export function createMethodsRPC(project: WorkspaceProject): RuntimeRPC {
@@ -25,12 +24,10 @@ export function createMethodsRPC(project: WorkspaceProject): RuntimeRPC {
2524
const r = await project.vitenode.transformRequest(id)
2625
return r?.map as RawSourceMap | undefined
2726
},
28-
fetch(id, environment) {
29-
const transformMode = getEnvironmentTransformMode(project.config, environment)
27+
fetch(id, transformMode) {
3028
return project.vitenode.fetchModule(id, transformMode)
3129
},
32-
resolveId(id, importer, environment) {
33-
const transformMode = getEnvironmentTransformMode(project.config, environment)
30+
resolveId(id, importer, transformMode) {
3431
return project.vitenode.resolveId(id, importer, transformMode)
3532
},
3633
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 } = ctx
13+
const { config, environment } = 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__ = config.environment
24+
globalThis.__vitest_environment__ = environment.name
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 } = await startViteNode(ctx)
80-
await run(ctx.files, ctx.config, ctx.environment, executor)
79+
const { run, executor, environment } = await startViteNode(ctx)
80+
await run(ctx.files, ctx.config, { ...ctx.environment, 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 { ContextTestEnvironment, ResolvedConfig } from '../types'
5+
import type { ResolvedConfig, ResolvedTestEnvironment } 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: ContextTestEnvironment, executor: VitestExecutor): Promise<void> {
92+
export async function run(files: string[], config: ResolvedConfig, environment: ResolvedTestEnvironment, 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
107+
globalThis.__vitest_environment__ = environment.name
108108

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

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

114114
for (const file of files) {

packages/vitest/src/runtime/execute.ts

+12-5
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ 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, ContextTestEnvironment, ResolvedConfig } from '../types'
9+
import type { ContextRPC, Environment, ResolvedConfig, ResolvedTestEnvironment } from '../types'
1010
import { distDir } from '../paths'
11+
import { loadEnvironment } from '../integrations/env'
1112
import { VitestMocker } from './mocker'
1213
import { rpc } from './rpc'
1314

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

2728
let _viteNode: {
28-
run: (files: string[], config: ResolvedConfig, environment: ContextTestEnvironment, executor: VitestExecutor) => Promise<void>
29+
run: (files: string[], config: ResolvedConfig, environment: ResolvedTestEnvironment, executor: VitestExecutor) => Promise<void>
2930
executor: VitestExecutor
31+
environment: Environment
3032
}
3133

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

66+
let transformMode: 'ssr' | 'web' = 'ssr'
67+
6468
const executor = await createVitestExecutor({
6569
fetchModule(id) {
66-
return rpc().fetch(id, ctx.environment.name)
70+
return rpc().fetch(id, transformMode)
6771
},
6872
resolveId(id, importer) {
69-
return rpc().resolveId(id, importer, ctx.environment.name)
73+
return rpc().resolveId(id, importer, transformMode)
7074
},
7175
moduleCache,
7276
mockMap,
@@ -76,9 +80,12 @@ export async function startViteNode(ctx: ContextRPC) {
7680
base: config.base,
7781
})
7882

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

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

8390
return _viteNode
8491
}

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

+6-21
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,14 @@ 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 { environments } from '../integrations/env'
6-
import type { Environment, ResolvedConfig } from '../types'
5+
import type { EnvironmentOptions, ResolvedConfig, ResolvedTestEnvironment } from '../types'
76
import { VitestSnapshotEnvironment } from '../integrations/snapshot/environments/node'
87
import { getSafeTimers, getWorkerState } from '../utils'
98
import * as VitestIndex from '../index'
109
import { RealDate } from '../integrations/mock/date'
1110
import { expect } from '../integrations/chai'
1211
import { rpc } from './rpc'
1312
import { setupCommonEnv } from './setup.common'
14-
import type { VitestExecutor } from './execute'
1513

1614
// this should only be used in Node
1715
let globalSetup = false
@@ -157,30 +155,17 @@ export async function setupConsoleLogSpy() {
157155
})
158156
}
159157

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-
171158
export async function withEnv(
172-
name: ResolvedConfig['environment'],
173-
options: ResolvedConfig['environmentOptions'],
174-
executor: VitestExecutor,
159+
{ environment, name }: ResolvedTestEnvironment,
160+
options: EnvironmentOptions,
175161
fn: () => Promise<void>,
176162
) {
177-
const config: Environment = (environments as any)[name] || await loadEnvironment(name, executor)
178163
// @ts-expect-error untyped global
179-
globalThis.__vitest_environment__ = config.name || name
164+
globalThis.__vitest_environment__ = name
180165
expect.setState({
181-
environment: config.name || name || 'node',
166+
environment: name,
182167
})
183-
const env = await config.setup(globalThis, options)
168+
const env = await environment.setup(globalThis, options)
184169
try {
185170
await fn()
186171
}

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
27+
globalThis.__vitest_environment__ = config.environment.name
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 } = await startViteNode(ctx)
66-
await run(ctx.files, ctx.config, ctx.environment, executor)
65+
const { run, executor, environment } = await startViteNode(ctx)
66+
await run(ctx.files, ctx.config, { ...ctx.environment, environment }, executor)
6767
await rpcDone()
6868
}
6969
finally {

packages/vitest/src/types/config.ts

-21
Original file line numberDiff line numberDiff line change
@@ -443,27 +443,6 @@ export interface InlineConfig {
443443
*/
444444
uiBase?: string
445445

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

packages/vitest/src/types/general.ts

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

2424
export interface Environment {
2525
name: string
26+
transformMode?: 'web' | 'ssr'
2627
setup(global: any, options: Record<string, any>): Awaitable<EnvironmentReturn>
2728
}
2829

0 commit comments

Comments
 (0)