@@ -2,9 +2,9 @@ import type { Vitest } from '../core'
2
2
import type { UserConfig , UserWorkspaceConfig , WorkspaceProjectConfiguration } from '../types/config'
3
3
import type { WorkspaceProject } from '../workspace'
4
4
import { existsSync , promises as fs } from 'node:fs'
5
- import { isMainThread } from 'node:worker_threads '
5
+ import { limitConcurrency } from '@vitest/runner/utils '
6
6
import fg from 'fast-glob'
7
- import { dirname , relative , resolve } from 'pathe'
7
+ import { relative , resolve } from 'pathe'
8
8
import { mergeConfig } from 'vite'
9
9
import { configFiles as defaultConfigFiles } from '../../constants'
10
10
import { initializeProject } from '../workspace'
@@ -49,63 +49,40 @@ export async function resolveWorkspace(
49
49
return acc
50
50
} , { } as UserConfig )
51
51
52
- const cwd = process . cwd ( )
53
-
54
- const projects : WorkspaceProject [ ] = [ ]
52
+ const projectPromises : Promise < WorkspaceProject > [ ] = [ ]
55
53
const fileProjects = [ ...configFiles , ...nonConfigDirectories ]
54
+ const concurrent = limitConcurrency ( 5 )
56
55
57
- try {
58
- // we have to resolve them one by one because CWD should depend on the project
59
- for ( const filepath of fileProjects ) {
60
- // if file leads to the root config, then we can just reuse it because we already initialized it
61
- if ( vitest . server . config . configFile === filepath ) {
62
- const project = await vitest . _createCoreProject ( )
63
- projects . push ( project )
64
- continue
65
- }
66
-
67
- const directory = filepath . endsWith ( '/' )
68
- ? filepath . slice ( 0 , - 1 )
69
- : dirname ( filepath )
70
-
71
- if ( isMainThread ) {
72
- process . chdir ( directory )
73
- }
74
- projects . push (
75
- await initializeProject (
76
- filepath ,
77
- vitest ,
78
- { workspaceConfigPath, test : cliOverrides } ,
79
- ) ,
80
- )
56
+ for ( const filepath of fileProjects ) {
57
+ // if file leads to the root config, then we can just reuse it because we already initialized it
58
+ if ( vitest . server . config . configFile === filepath ) {
59
+ projectPromises . push ( concurrent ( ( ) => vitest . _createCoreProject ( ) ) )
60
+ continue
81
61
}
82
- }
83
- finally {
84
- if ( isMainThread ) {
85
- process . chdir ( cwd )
86
- }
87
- }
88
62
89
- const projectPromises : Promise < WorkspaceProject > [ ] = [ ]
63
+ projectPromises . push (
64
+ concurrent ( ( ) => initializeProject (
65
+ filepath ,
66
+ vitest ,
67
+ { workspaceConfigPath, test : cliOverrides } ,
68
+ ) ) ,
69
+ )
70
+ }
90
71
91
72
projectConfigs . forEach ( ( options , index ) => {
92
- // we can resolve these in parallel because process.cwd() is not changed
93
- projectPromises . push ( initializeProject (
73
+ projectPromises . push ( concurrent ( ( ) => initializeProject (
94
74
index ,
95
75
vitest ,
96
76
mergeConfig ( options , { workspaceConfigPath, test : cliOverrides } ) as any ,
97
- ) )
77
+ ) ) )
98
78
} )
99
79
100
80
// pretty rare case - the glob didn't match anything and there are no inline configs
101
- if ( ! projects . length && ! projectPromises . length ) {
81
+ if ( ! projectPromises . length ) {
102
82
return [ await vitest . _createCoreProject ( ) ]
103
83
}
104
84
105
- const resolvedProjects = await Promise . all ( [
106
- ...projects ,
107
- ...projectPromises ,
108
- ] )
85
+ const resolvedProjects = await Promise . all ( projectPromises )
109
86
const names = new Set < string > ( )
110
87
111
88
// project names are guaranteed to be unique
0 commit comments