@@ -2,9 +2,9 @@ import type { Vitest } from '../core'
22import type { UserConfig , UserWorkspaceConfig , WorkspaceProjectConfiguration } from '../types/config'
33import type { WorkspaceProject } from '../workspace'
44import { existsSync , promises as fs } from 'node:fs'
5- import { isMainThread } from 'node:worker_threads '
5+ import { limitConcurrency } from '@vitest/runner/utils '
66import fg from 'fast-glob'
7- import { dirname , relative , resolve } from 'pathe'
7+ import { relative , resolve } from 'pathe'
88import { mergeConfig } from 'vite'
99import { configFiles as defaultConfigFiles } from '../../constants'
1010import { initializeProject } from '../workspace'
@@ -49,63 +49,40 @@ export async function resolveWorkspace(
4949 return acc
5050 } , { } as UserConfig )
5151
52- const cwd = process . cwd ( )
53-
54- const projects : WorkspaceProject [ ] = [ ]
52+ const projectPromises : Promise < WorkspaceProject > [ ] = [ ]
5553 const fileProjects = [ ...configFiles , ...nonConfigDirectories ]
54+ const concurrent = limitConcurrency ( 5 )
5655
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
8161 }
82- }
83- finally {
84- if ( isMainThread ) {
85- process . chdir ( cwd )
86- }
87- }
8862
89- const projectPromises : Promise < WorkspaceProject > [ ] = [ ]
63+ projectPromises . push (
64+ concurrent ( ( ) => initializeProject (
65+ filepath ,
66+ vitest ,
67+ { workspaceConfigPath, test : cliOverrides } ,
68+ ) ) ,
69+ )
70+ }
9071
9172 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 (
9474 index ,
9575 vitest ,
9676 mergeConfig ( options , { workspaceConfigPath, test : cliOverrides } ) as any ,
97- ) )
77+ ) ) )
9878 } )
9979
10080 // 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 ) {
10282 return [ await vitest . _createCoreProject ( ) ]
10383 }
10484
105- const resolvedProjects = await Promise . all ( [
106- ...projects ,
107- ...projectPromises ,
108- ] )
85+ const resolvedProjects = await Promise . all ( projectPromises )
10986 const names = new Set < string > ( )
11087
11188 // project names are guaranteed to be unique
0 commit comments