1
1
import { pathToFileURL } from 'node:url'
2
+ import mm from 'micromatch'
2
3
import { resolve } from 'pathe'
3
4
import { distDir , rootDir } from '../constants'
5
+ import type { VitestPool } from '../types'
4
6
import type { Vitest } from './core'
5
7
import { createChildProcessPool } from './pools/child'
6
8
import { createThreadsPool } from './pools/threads'
@@ -21,38 +23,92 @@ const loaderPath = pathToFileURL(resolve(distDir, './loader.js')).href
21
23
const suppressLoaderWarningsPath = resolve ( rootDir , './suppress-warnings.cjs' )
22
24
23
25
export function createPool ( ctx : Vitest ) : ProcessPool {
24
- const conditions = ctx . server . config . resolve . conditions ?. flatMap ( c => [ '--conditions' , c ] ) || [ ]
25
-
26
- // Instead of passing whole process.execArgv to the workers, pick allowed options.
27
- // Some options may crash worker, e.g. --prof, --title. nodejs/node#41103
28
- const execArgv = process . execArgv . filter ( execArg =>
29
- execArg . startsWith ( '--cpu-prof' ) || execArg . startsWith ( '--heap-prof' ) ,
30
- )
31
-
32
- const options : PoolProcessOptions = {
33
- execArgv : ctx . config . deps . registerNodeLoader
34
- ? [
35
- ...execArgv ,
36
- '--require' ,
37
- suppressLoaderWarningsPath ,
38
- '--experimental-loader' ,
39
- loaderPath ,
40
- ]
41
- : [
42
- ...execArgv ,
43
- ...conditions ,
44
- ] ,
45
- env : {
46
- TEST : 'true' ,
47
- VITEST : 'true' ,
48
- NODE_ENV : ctx . config . mode || 'test' ,
49
- VITEST_MODE : ctx . config . watch ? 'WATCH' : 'RUN' ,
50
- ...process . env ,
51
- ...ctx . config . env ,
52
- } ,
26
+ const pools : Record < VitestPool , ProcessPool | null > = {
27
+ child_process : null ,
28
+ threads : null ,
29
+ }
30
+
31
+ function getDefaultPoolName ( ) {
32
+ if ( ctx . config . threads )
33
+ return 'threads'
34
+ return 'child_process'
35
+ }
36
+
37
+ function getPoolName ( file : string ) {
38
+ for ( const [ glob , pool ] of ctx . config . poolMatchGlobs || [ ] ) {
39
+ if ( mm . isMatch ( file , glob , { cwd : ctx . server . config . root } ) )
40
+ return pool
41
+ }
42
+ return getDefaultPoolName ( )
43
+ }
44
+
45
+ async function runTests ( files : string [ ] , invalidate ?: string [ ] ) {
46
+ const conditions = ctx . server . config . resolve . conditions ?. flatMap ( c => [ '--conditions' , c ] ) || [ ]
47
+
48
+ // Instead of passing whole process.execArgv to the workers, pick allowed options.
49
+ // Some options may crash worker, e.g. --prof, --title. nodejs/node#41103
50
+ const execArgv = process . execArgv . filter ( execArg =>
51
+ execArg . startsWith ( '--cpu-prof' ) || execArg . startsWith ( '--heap-prof' ) ,
52
+ )
53
+
54
+ const options : PoolProcessOptions = {
55
+ execArgv : ctx . config . deps . registerNodeLoader
56
+ ? [
57
+ ...execArgv ,
58
+ '--require' ,
59
+ suppressLoaderWarningsPath ,
60
+ '--experimental-loader' ,
61
+ loaderPath ,
62
+ ]
63
+ : [
64
+ ...execArgv ,
65
+ ...conditions ,
66
+ ] ,
67
+ env : {
68
+ TEST : 'true' ,
69
+ VITEST : 'true' ,
70
+ NODE_ENV : ctx . config . mode || 'test' ,
71
+ VITEST_MODE : ctx . config . watch ? 'WATCH' : 'RUN' ,
72
+ ...process . env ,
73
+ ...ctx . config . env ,
74
+ } ,
75
+ }
76
+
77
+ const filesByPool = {
78
+ child_process : [ ] as string [ ] ,
79
+ threads : [ ] as string [ ] ,
80
+ browser : [ ] as string [ ] ,
81
+ }
82
+
83
+ if ( ! ctx . config . poolMatchGlobs ) {
84
+ const name = getDefaultPoolName ( )
85
+ filesByPool [ name ] = files
86
+ }
87
+ else {
88
+ for ( const file of files ) {
89
+ const pool = getPoolName ( file )
90
+ filesByPool [ pool ] . push ( file )
91
+ }
92
+ }
93
+
94
+ await Promise . all ( Object . entries ( filesByPool ) . map ( ( [ pool , files ] ) => {
95
+ if ( ! files . length )
96
+ return null
97
+
98
+ if ( pool === 'threads' ) {
99
+ pools . threads ??= createThreadsPool ( ctx , options )
100
+ return pools . threads . runTests ( files , invalidate )
101
+ }
102
+
103
+ pools . child_process ??= createChildProcessPool ( ctx , options )
104
+ return pools . child_process . runTests ( files , invalidate )
105
+ } ) )
53
106
}
54
107
55
- if ( ! ctx . config . threads )
56
- return createChildProcessPool ( ctx , options )
57
- return createThreadsPool ( ctx , options )
108
+ return {
109
+ runTests,
110
+ async close ( ) {
111
+ await Promise . all ( Object . values ( pools ) . map ( p => p ?. close ( ) ) )
112
+ } ,
113
+ }
58
114
}
0 commit comments