@@ -15,6 +15,7 @@ import {EntryPoint, EntryPointJsonProperty, getEntryPointInfo, INCOMPATIBLE_ENTR
15
15
import { PathMappings } from '../path_mappings' ;
16
16
17
17
import { EntryPointFinder } from './interface' ;
18
+ import { TracingEntryPointFinder } from './tracing_entry_point_finder' ;
18
19
import { getBasePaths } from './utils' ;
19
20
20
21
/**
@@ -24,30 +25,16 @@ import {getBasePaths} from './utils';
24
25
* This is faster than searching the entire file-system for all the entry-points,
25
26
* and is used primarily by the CLI integration.
26
27
*/
27
- export class TargetedEntryPointFinder implements EntryPointFinder {
28
- private unprocessedPaths : AbsoluteFsPath [ ] = [ ] ;
29
- private unsortedEntryPoints = new Map < AbsoluteFsPath , EntryPointWithDependencies > ( ) ;
30
- private basePaths : AbsoluteFsPath [ ] | null = null ;
31
- private getBasePaths ( ) {
32
- if ( this . basePaths === null ) {
33
- this . basePaths = getBasePaths ( this . logger , this . basePath , this . pathMappings ) ;
34
- }
35
- return this . basePaths ;
36
- }
37
-
28
+ export class TargetedEntryPointFinder extends TracingEntryPointFinder {
38
29
constructor (
39
- private fs : FileSystem , private config : NgccConfiguration , private logger : Logger ,
40
- private resolver : DependencyResolver , private basePath : AbsoluteFsPath ,
41
- private targetPath : AbsoluteFsPath , private pathMappings : PathMappings | undefined ) { }
30
+ fs : FileSystem , config : NgccConfiguration , logger : Logger , resolver : DependencyResolver ,
31
+ basePath : AbsoluteFsPath , pathMappings : PathMappings | undefined ,
32
+ private targetPath : AbsoluteFsPath ) {
33
+ super ( fs , config , logger , resolver , basePath , pathMappings ) ;
34
+ }
42
35
43
36
findEntryPoints ( ) : SortedEntryPointsInfo {
44
- this . unprocessedPaths = [ this . targetPath ] ;
45
- while ( this . unprocessedPaths . length > 0 ) {
46
- this . processNextPath ( ) ;
47
- }
48
- const targetEntryPoint = this . unsortedEntryPoints . get ( this . targetPath ) ;
49
- const entryPoints = this . resolver . sortEntryPointsByDependency (
50
- Array . from ( this . unsortedEntryPoints . values ( ) ) , targetEntryPoint ?. entryPoint ) ;
37
+ const entryPoints = super . findEntryPoints ( ) ;
51
38
52
39
const invalidTarget =
53
40
entryPoints . invalidEntryPoints . find ( i => i . entryPoint . path === this . targetPath ) ;
@@ -83,149 +70,7 @@ export class TargetedEntryPointFinder implements EntryPointFinder {
83
70
return false ;
84
71
}
85
72
86
- private processNextPath ( ) : void {
87
- const path = this . unprocessedPaths . shift ( ) ! ;
88
- const entryPoint = this . getEntryPoint ( path ) ;
89
- if ( entryPoint === null || ! entryPoint . compiledByAngular ) {
90
- return ;
91
- }
92
- const entryPointWithDeps = this . resolver . getEntryPointWithDependencies ( entryPoint ) ;
93
- this . unsortedEntryPoints . set ( entryPoint . path , entryPointWithDeps ) ;
94
- entryPointWithDeps . depInfo . dependencies . forEach ( dep => {
95
- if ( ! this . unsortedEntryPoints . has ( dep ) ) {
96
- this . unprocessedPaths . push ( dep ) ;
97
- }
98
- } ) ;
99
- }
100
-
101
- private getEntryPoint ( entryPointPath : AbsoluteFsPath ) : EntryPoint | null {
102
- const packagePath = this . computePackagePath ( entryPointPath ) ;
103
- const entryPoint =
104
- getEntryPointInfo ( this . fs , this . config , this . logger , packagePath , entryPointPath ) ;
105
- if ( entryPoint === NO_ENTRY_POINT || entryPoint === INCOMPATIBLE_ENTRY_POINT ) {
106
- return null ;
107
- }
108
- return entryPoint ;
109
- }
110
-
111
- private computePackagePath ( entryPointPath : AbsoluteFsPath ) : AbsoluteFsPath {
112
- // First try the main basePath, to avoid having to compute the other basePaths from the paths
113
- // mappings, which can be computationally intensive.
114
- if ( entryPointPath . startsWith ( this . basePath ) ) {
115
- const packagePath = this . computePackagePathFromContainingPath ( entryPointPath , this . basePath ) ;
116
- if ( packagePath !== null ) {
117
- return packagePath ;
118
- }
119
- }
120
-
121
- // The main `basePath` didn't work out so now we try the `basePaths` computed from the paths
122
- // mappings in `tsconfig.json`.
123
- for ( const basePath of this . getBasePaths ( ) ) {
124
- if ( entryPointPath . startsWith ( basePath ) ) {
125
- const packagePath = this . computePackagePathFromContainingPath ( entryPointPath , basePath ) ;
126
- if ( packagePath !== null ) {
127
- return packagePath ;
128
- }
129
- // If we got here then we couldn't find a `packagePath` for the current `basePath`.
130
- // Since `basePath`s are guaranteed not to be a sub-directory of each other then no other
131
- // `basePath` will match either.
132
- break ;
133
- }
134
- }
135
-
136
- // Finally, if we couldn't find a `packagePath` using `basePaths` then try to find the nearest
137
- // `node_modules` that contains the `entryPointPath`, if there is one, and use it as a
138
- // `basePath`.
139
- return this . computePackagePathFromNearestNodeModules ( entryPointPath ) ;
140
- }
141
-
142
- /**
143
- * Search down to the `entryPointPath` from the `containingPath` for the first `package.json` that
144
- * we come to. This is the path to the entry-point's containing package. For example if
145
- * `containingPath` is `/a/b/c` and `entryPointPath` is `/a/b/c/d/e` and there exists
146
- * `/a/b/c/d/package.json` and `/a/b/c/d/e/package.json`, then we will return `/a/b/c/d`.
147
- *
148
- * To account for nested `node_modules` we actually start the search at the last `node_modules` in
149
- * the `entryPointPath` that is below the `containingPath`. E.g. if `containingPath` is `/a/b/c`
150
- * and `entryPointPath` is `/a/b/c/d/node_modules/x/y/z`, we start the search at
151
- * `/a/b/c/d/node_modules`.
152
- */
153
- private computePackagePathFromContainingPath (
154
- entryPointPath : AbsoluteFsPath , containingPath : AbsoluteFsPath ) : AbsoluteFsPath | null {
155
- let packagePath = containingPath ;
156
- const segments = this . splitPath ( relative ( containingPath , entryPointPath ) ) ;
157
- let nodeModulesIndex = segments . lastIndexOf ( relativeFrom ( 'node_modules' ) ) ;
158
-
159
- // If there are no `node_modules` in the relative path between the `basePath` and the
160
- // `entryPointPath` then just try the `basePath` as the `packagePath`.
161
- // (This can be the case with path-mapped entry-points.)
162
- if ( nodeModulesIndex === - 1 ) {
163
- if ( this . fs . exists ( join ( packagePath , 'package.json' ) ) ) {
164
- return packagePath ;
165
- }
166
- }
167
-
168
- // Start the search at the deepest nested `node_modules` folder that is below the `basePath`
169
- // but above the `entryPointPath`, if there are any.
170
- while ( nodeModulesIndex >= 0 ) {
171
- packagePath = join ( packagePath , segments . shift ( ) ! ) ;
172
- nodeModulesIndex -- ;
173
- }
174
-
175
- // Note that we start at the folder below the current candidate `packagePath` because the
176
- // initial candidate `packagePath` is either a `node_modules` folder or the `basePath` with
177
- // no `package.json`.
178
- for ( const segment of segments ) {
179
- packagePath = join ( packagePath , segment ) ;
180
- if ( this . fs . exists ( join ( packagePath , 'package.json' ) ) ) {
181
- return packagePath ;
182
- }
183
- }
184
- return null ;
185
- }
186
-
187
- /**
188
- * Search up the directory tree from the `entryPointPath` looking for a `node_modules` directory
189
- * that we can use as a potential starting point for computing the package path.
190
- */
191
- private computePackagePathFromNearestNodeModules ( entryPointPath : AbsoluteFsPath ) : AbsoluteFsPath {
192
- let packagePath = entryPointPath ;
193
- let scopedPackagePath = packagePath ;
194
- let containerPath = this . fs . dirname ( packagePath ) ;
195
- while ( ! this . fs . isRoot ( containerPath ) && ! containerPath . endsWith ( 'node_modules' ) ) {
196
- scopedPackagePath = packagePath ;
197
- packagePath = containerPath ;
198
- containerPath = this . fs . dirname ( containerPath ) ;
199
- }
200
-
201
- if ( this . fs . exists ( join ( packagePath , 'package.json' ) ) ) {
202
- // The directory directly below `node_modules` is a package - use it
203
- return packagePath ;
204
- } else if (
205
- this . fs . basename ( packagePath ) . startsWith ( '@' ) &&
206
- this . fs . exists ( join ( scopedPackagePath , 'package.json' ) ) ) {
207
- // The directory directly below the `node_modules` is a scope and the directory directly
208
- // below that is a scoped package - use it
209
- return scopedPackagePath ;
210
- } else {
211
- // If we get here then none of the `basePaths` contained the `entryPointPath` and the
212
- // `entryPointPath` contains no `node_modules` that contains a package or a scoped
213
- // package. All we can do is assume that this entry-point is a primary entry-point to a
214
- // package.
215
- return entryPointPath ;
216
- }
217
- }
218
-
219
- /**
220
- * Split the given `path` into path segments using an FS independent algorithm.
221
- * @param path The path to split.
222
- */
223
- private splitPath ( path : PathSegment ) {
224
- const segments = [ ] ;
225
- while ( path !== '.' ) {
226
- segments . unshift ( this . fs . basename ( path ) ) ;
227
- path = this . fs . dirname ( path ) ;
228
- }
229
- return segments ;
73
+ protected getInitialEntryPointPaths ( ) : AbsoluteFsPath [ ] {
74
+ return [ this . targetPath ] ;
230
75
}
231
76
}
0 commit comments