@@ -9,8 +9,9 @@ import {AbsoluteFsPath, FileSystem, join, resolve} from '../../../src/ngtsc/file
99import { DependencyResolver , SortedEntryPointsInfo } from '../dependencies/dependency_resolver' ;
1010import { Logger } from '../logging/logger' ;
1111import { NgccConfiguration } from '../packages/configuration' ;
12- import { EntryPoint , getEntryPointInfo } from '../packages/entry_point' ;
12+ import { EntryPoint , INVALID_ENTRY_POINT , NO_ENTRY_POINT , getEntryPointInfo } from '../packages/entry_point' ;
1313import { PathMappings } from '../utils' ;
14+ import { NGCC_DIRECTORY } from '../writing/new_entry_point_file_writer' ;
1415import { EntryPointFinder } from './interface' ;
1516import { getBasePaths } from './utils' ;
1617
@@ -40,10 +41,24 @@ export class DirectoryWalkerEntryPointFinder implements EntryPointFinder {
4041 * The function will recurse into directories that start with `@...`, e.g. `@angular/...`.
4142 * @param sourceDirectory An absolute path to the root directory where searching begins.
4243 */
43- private walkDirectoryForEntryPoints ( sourceDirectory : AbsoluteFsPath ) : EntryPoint [ ] {
44+ walkDirectoryForEntryPoints ( sourceDirectory : AbsoluteFsPath ) : EntryPoint [ ] {
4445 const entryPoints = this . getEntryPointsForPackage ( sourceDirectory ) ;
46+ if ( entryPoints === null ) {
47+ return [ ] ;
48+ }
49+
4550 if ( entryPoints . length > 0 ) {
46- // The `sourceDirectory` is an entry-point itself so no need to search its sub-directories.
51+ // The `sourceDirectory` is an entry point itself so no need to search its sub-directories.
52+ // Also check for any nested node_modules in this package but only if it was compiled by
53+ // Angular.
54+ // It is unlikely that a non Angular entry point has a dependency on an Angular library.
55+ if ( entryPoints . some ( e => e . compiledByAngular ) ) {
56+ const nestedNodeModulesPath = this . fs . join ( sourceDirectory , 'node_modules' ) ;
57+ if ( this . fs . exists ( nestedNodeModulesPath ) ) {
58+ entryPoints . push ( ...this . walkDirectoryForEntryPoints ( nestedNodeModulesPath ) ) ;
59+ }
60+ }
61+
4762 return entryPoints ;
4863 }
4964
@@ -52,54 +67,57 @@ export class DirectoryWalkerEntryPointFinder implements EntryPointFinder {
5267 // Not interested in hidden files
5368 . filter ( p => ! p . startsWith ( '.' ) )
5469 // Ignore node_modules
55- . filter ( p => p !== 'node_modules' )
70+ . filter ( p => p !== 'node_modules' && p !== NGCC_DIRECTORY )
5671 // Only interested in directories (and only those that are not symlinks)
5772 . filter ( p => {
5873 const stat = this . fs . lstat ( resolve ( sourceDirectory , p ) ) ;
5974 return stat . isDirectory ( ) && ! stat . isSymbolicLink ( ) ;
6075 } )
6176 . forEach ( p => {
62- // Either the directory is a potential package or a namespace containing packages (e.g
63- // `@angular`).
77+ // Package is a potential namespace containing packages (e.g `@angular`).
6478 const packagePath = join ( sourceDirectory , p ) ;
6579 entryPoints . push ( ...this . walkDirectoryForEntryPoints ( packagePath ) ) ;
66-
67- // Also check for any nested node_modules in this package
68- const nestedNodeModulesPath = join ( packagePath , 'node_modules' ) ;
69- if ( this . fs . exists ( nestedNodeModulesPath ) ) {
70- entryPoints . push ( ...this . walkDirectoryForEntryPoints ( nestedNodeModulesPath ) ) ;
71- }
7280 } ) ;
7381 return entryPoints ;
7482 }
7583
7684 /**
7785 * Recurse the folder structure looking for all the entry points
7886 * @param packagePath The absolute path to an npm package that may contain entry points
79- * @returns An array of entry points that were discovered.
87+ * @returns An array of entry points that were discovered or null when it's not a valid entrypoint
8088 */
81- private getEntryPointsForPackage ( packagePath : AbsoluteFsPath ) : EntryPoint [ ] {
89+ private getEntryPointsForPackage ( packagePath : AbsoluteFsPath ) : EntryPoint [ ] | null {
8290 const entryPoints : EntryPoint [ ] = [ ] ;
8391
8492 // Try to get an entry point from the top level package directory
8593 const topLevelEntryPoint =
8694 getEntryPointInfo ( this . fs , this . config , this . logger , packagePath , packagePath ) ;
8795
8896 // If there is no primary entry-point then exit
89- if ( topLevelEntryPoint === null ) {
97+ if ( topLevelEntryPoint === NO_ENTRY_POINT ) {
9098 return [ ] ;
9199 }
92100
101+ if ( topLevelEntryPoint === INVALID_ENTRY_POINT ) {
102+ return null ;
103+ }
104+
93105 // Otherwise store it and search for secondary entry-points
94106 entryPoints . push ( topLevelEntryPoint ) ;
95107 this . walkDirectory ( packagePath , packagePath , ( path , isDirectory ) => {
108+ if ( ! path . endsWith ( '.js' ) && ! isDirectory ) {
109+ return false ;
110+ }
111+
96112 // If the path is a JS file then strip its extension and see if we can match an entry-point.
97113 const possibleEntryPointPath = isDirectory ? path : stripJsExtension ( path ) ;
98114 const subEntryPoint =
99115 getEntryPointInfo ( this . fs , this . config , this . logger , packagePath , possibleEntryPointPath ) ;
100- if ( subEntryPoint !== null ) {
101- entryPoints . push ( subEntryPoint ) ;
116+ if ( subEntryPoint === NO_ENTRY_POINT || subEntryPoint === INVALID_ENTRY_POINT ) {
117+ return false ;
102118 }
119+ entryPoints . push ( subEntryPoint ) ;
120+ return true ;
103121 } ) ;
104122
105123 return entryPoints ;
@@ -113,26 +131,25 @@ export class DirectoryWalkerEntryPointFinder implements EntryPointFinder {
113131 */
114132 private walkDirectory (
115133 packagePath : AbsoluteFsPath , dir : AbsoluteFsPath ,
116- fn : ( path : AbsoluteFsPath , isDirectory : boolean ) => void ) {
134+ fn : ( path : AbsoluteFsPath , isDirectory : boolean ) => boolean ) {
117135 return this . fs
118136 . readdir ( dir )
119137 // Not interested in hidden files
120138 . filter ( path => ! path . startsWith ( '.' ) )
121139 // Ignore node_modules
122- . filter ( path => path !== 'node_modules' )
123- . map ( path => resolve ( dir , path ) )
140+ . filter ( path => path !== 'node_modules' && path !== NGCC_DIRECTORY )
124141 . forEach ( path => {
125- const stat = this . fs . lstat ( path ) ;
142+ const absolutePath = resolve ( dir , path ) ;
143+ const stat = this . fs . lstat ( absolutePath ) ;
126144
127145 if ( stat . isSymbolicLink ( ) ) {
128146 // We are not interested in symbolic links
129147 return ;
130148 }
131149
132- fn ( path , stat . isDirectory ( ) ) ;
133-
134- if ( stat . isDirectory ( ) ) {
135- this . walkDirectory ( packagePath , path , fn ) ;
150+ const containsEntryPoint = fn ( absolutePath , stat . isDirectory ( ) ) ;
151+ if ( containsEntryPoint ) {
152+ this . walkDirectory ( packagePath , absolutePath , fn ) ;
136153 }
137154 } ) ;
138155 }
0 commit comments