@@ -613,31 +613,26 @@ export class AngularCompilerPlugin {
613613 // - __ng_typecheck__.ts will never be requested.
614614 const fileExcludeRegExp = / ( \. ( d | n g f a c t o r y | n g s t y l e | n g s u m m a r y ) \. t s | n g _ t y p e c h e c k _ _ \. t s ) $ / ;
615615
616- const usedFiles = new Set < string > ( ) ;
617- for ( const compilationModule of compilation . modules ) {
618- if ( ! compilationModule . resource ) {
619- continue ;
616+ // Start with a set of all the source file names we care about.
617+ const unusedSourceFileNames = new Set (
618+ program . getSourceFiles ( )
619+ . map ( x => this . _compilerHost . denormalizePath ( x . fileName ) )
620+ . filter ( f => ! ( fileExcludeRegExp . test ( f ) || this . _unusedFiles . has ( f ) ) ) ,
621+ ) ;
622+ // This function removes a source file name and all its dependencies from the set.
623+ const removeSourceFile = ( fileName : string ) => {
624+ if ( unusedSourceFileNames . has ( fileName ) ) {
625+ unusedSourceFileNames . delete ( fileName ) ;
626+ this . getDependencies ( fileName , false ) . forEach ( f => removeSourceFile ( f ) ) ;
620627 }
628+ } ;
621629
622- usedFiles . add ( forwardSlashPath ( compilationModule . resource ) ) ;
623-
624- // We need the below for dependencies which
625- // are not emitted such as type only TS files
626- for ( const dependency of compilationModule . buildInfo . fileDependencies ) {
627- usedFiles . add ( forwardSlashPath ( dependency ) ) ;
628- }
629- }
630-
631- const sourceFiles = program . getSourceFiles ( ) ;
632- for ( const { fileName } of sourceFiles ) {
633- if (
634- fileExcludeRegExp . test ( fileName )
635- || usedFiles . has ( fileName )
636- || this . _unusedFiles . has ( fileName )
637- ) {
638- continue ;
639- }
630+ // Go over all the modules in the webpack compilation and remove them from the set.
631+ compilation . modules . forEach ( m => m . resource ? removeSourceFile ( m . resource ) : null ) ;
640632
633+ // Anything that remains is unused, because it wasn't referenced directly or transitively
634+ // on the files in the compilation.
635+ for ( const fileName of unusedSourceFileNames ) {
641636 compilation . warnings . push (
642637 `${ fileName } is part of the TypeScript compilation but it's unused.\n` +
643638 `Add only entry points to the 'files' or 'include' properties in your tsconfig.` ,
@@ -1210,7 +1205,7 @@ export class AngularCompilerPlugin {
12101205 return { outputText, sourceMap, errorDependencies } ;
12111206 }
12121207
1213- getDependencies ( fileName : string ) : string [ ] {
1208+ getDependencies ( fileName : string , includeResources = true ) : string [ ] {
12141209 const resolvedFileName = this . _compilerHost . resolve ( fileName ) ;
12151210 const sourceFile = this . _compilerHost . getSourceFile ( resolvedFileName , ts . ScriptTarget . Latest ) ;
12161211 if ( ! sourceFile ) {
@@ -1244,14 +1239,19 @@ export class AngularCompilerPlugin {
12441239 } )
12451240 . filter ( x => x ) as string [ ] ;
12461241
1247- const resourceImports = findResources ( sourceFile )
1248- . map ( resourcePath => resolve ( dirname ( resolvedFileName ) , normalize ( resourcePath ) ) ) ;
1242+ let resourceImports : string [ ] = [ ] , resourceDependencies : string [ ] = [ ] ;
1243+ if ( includeResources ) {
1244+ resourceImports = findResources ( sourceFile )
1245+ . map ( resourcePath => resolve ( dirname ( resolvedFileName ) , normalize ( resourcePath ) ) ) ;
1246+ resourceDependencies =
1247+ this . getResourceDependencies ( this . _compilerHost . denormalizePath ( resolvedFileName ) ) ;
1248+ }
12491249
12501250 // These paths are meant to be used by the loader so we must denormalize them.
12511251 const uniqueDependencies = new Set ( [
12521252 ...esImports ,
12531253 ...resourceImports ,
1254- ...this . getResourceDependencies ( this . _compilerHost . denormalizePath ( resolvedFileName ) ) ,
1254+ ...resourceDependencies ,
12551255 ] . map ( ( p ) => p && this . _compilerHost . denormalizePath ( p ) ) ) ;
12561256
12571257 return [ ...uniqueDependencies ] ;
0 commit comments