@@ -50,9 +50,6 @@ export const createNodes: CreateNodes<EslintPluginOptions> = [
50
50
}
51
51
}
52
52
53
- const childProjectRoots = new Set < string > ( ) ;
54
- const ESLint = resolveESLintClass ( isFlatConfig ( configFilePath ) ) ;
55
-
56
53
const projectFiles = globWithWorkspaceContext (
57
54
context . workspaceRoot ,
58
55
[
@@ -63,28 +60,40 @@ export const createNodes: CreateNodes<EslintPluginOptions> = [
63
60
] . map ( ( f ) => join ( configDir , f ) ) ,
64
61
nestedEslintRootPatterns . length ? nestedEslintRootPatterns : undefined
65
62
) ;
66
- for ( const projectFile of projectFiles ) {
67
- const childProjectRoot = dirname ( projectFile ) ;
68
- if ( childProjectRoots . has ( childProjectRoot ) ) {
69
- continue ;
70
- }
63
+ // dedupe and sort project roots by depth for more efficient traversal
64
+ const dedupedProjectRoots = Array . from (
65
+ new Set ( projectFiles . map ( ( f ) => dirname ( f ) ) )
66
+ ) . sort ( ( a , b ) => ( a !== b && isSubDir ( a , b ) ? - 1 : 1 ) ) ;
67
+ const excludePatterns = dedupedProjectRoots . map ( ( root ) => ` ${ root } /**/*` ) ;
71
68
72
- // Ignore project roots where the project does not contain any lintable files
73
- const lintableFiles = globWithWorkspaceContext (
74
- context . workspaceRoot ,
75
- [ join ( childProjectRoot , `**/*.{${ options . extensions . join ( ',' ) } }` ) ] ,
76
- nestedEslintRootPatterns . length ? nestedEslintRootPatterns : undefined
77
- ) ;
78
- const eslint = new ESLint ( {
79
- cwd : join ( context . workspaceRoot , childProjectRoot ) ,
80
- } ) ;
81
- for ( const file of lintableFiles ) {
82
- if ( ! ( await eslint . isPathIgnored ( join ( context . workspaceRoot , file ) ) ) ) {
83
- childProjectRoots . add ( childProjectRoot ) ;
84
- break ;
69
+ const ESLint = resolveESLintClass ( isFlatConfig ( configFilePath ) ) ;
70
+ const childProjectRoots = new Set < string > ( ) ;
71
+
72
+ await Promise . all (
73
+ dedupedProjectRoots . map ( async ( childProjectRoot , index ) => {
74
+ // anything after is either a nested project or a sibling project, can be excluded
75
+ const nestedProjectRootPatterns = excludePatterns . slice ( index + 1 ) ;
76
+
77
+ // Ignore project roots where the project does not contain any lintable files
78
+ const lintableFiles = globWithWorkspaceContext (
79
+ context . workspaceRoot ,
80
+ [ join ( childProjectRoot , `**/*.{${ options . extensions . join ( ',' ) } }` ) ] ,
81
+ // exclude nested eslint roots and nested project roots
82
+ [ ...nestedEslintRootPatterns , ...nestedProjectRootPatterns ]
83
+ ) ;
84
+ const eslint = new ESLint ( {
85
+ cwd : join ( context . workspaceRoot , childProjectRoot ) ,
86
+ } ) ;
87
+ for ( const file of lintableFiles ) {
88
+ if (
89
+ ! ( await eslint . isPathIgnored ( join ( context . workspaceRoot , file ) ) )
90
+ ) {
91
+ childProjectRoots . add ( childProjectRoot ) ;
92
+ break ;
93
+ }
85
94
}
86
- }
87
- }
95
+ } )
96
+ ) ;
88
97
89
98
const uniqueChildProjectRoots = Array . from ( childProjectRoots ) ;
90
99
0 commit comments