diff --git a/packages/compiler-cli/src/ngtsc/core/src/compiler.ts b/packages/compiler-cli/src/ngtsc/core/src/compiler.ts index f783c8ae60..a867e72613 100644 --- a/packages/compiler-cli/src/ngtsc/core/src/compiler.ts +++ b/packages/compiler-cli/src/ngtsc/core/src/compiler.ts @@ -162,6 +162,17 @@ export class NgCompiler { this.ignoreForEmit = this.adapter.ignoreForEmit; } + /** + * Get the resource dependencies of a file. + * + * If the file is not part of the compilation, an empty array will be returned. + */ + getResourceDependencies(file: ts.SourceFile): string[] { + this.ensureAnalyzed(); + + return this.incrementalDriver.depGraph.getResourceDependencies(file); + } + /** * Get all Angular-related diagnostics for this compilation. * diff --git a/packages/compiler-cli/src/ngtsc/core/test/compiler_test.ts b/packages/compiler-cli/src/ngtsc/core/test/compiler_test.ts index 0a6b3ac118..9e873e720e 100644 --- a/packages/compiler-cli/src/ngtsc/core/test/compiler_test.ts +++ b/packages/compiler-cli/src/ngtsc/core/test/compiler_test.ts @@ -105,6 +105,40 @@ runInEachFileSystem(() => { expect(components).toEqual(new Set([CmpA, CmpC])); }); }); + + describe('getResourceDependencies', () => { + it('should return resource dependencies of a component source file', () => { + const COMPONENT = _('/cmp.ts'); + fs.writeFile(COMPONENT, ` + import {Component} from '@angular/core'; + @Component({ + selector: 'test-cmp', + templateUrl: './template.html', + styleUrls: ['./style.css'], + }) + export class Cmp {} + `); + fs.writeFile(_('/template.html'), `

Resource

`); + fs.writeFile(_('/style.css'), `h1 { }`); + + const options: NgCompilerOptions = { + strictTemplates: true, + }; + const baseHost = new NgtscCompilerHost(getFileSystem(), options); + const host = NgCompilerHost.wrap(baseHost, [COMPONENT], options, /* oldProgram */ null); + const program = ts.createProgram({host, options, rootNames: host.inputFiles}); + const compiler = new NgCompiler( + host, options, program, new ReusedProgramStrategy(program, host, options, []), + new NoopIncrementalBuildStrategy(), /** enableTemplateTypeChecker */ false); + + const deps = compiler.getResourceDependencies(getSourceFileOrError(program, COMPONENT)); + expect(deps.length).toBe(2); + expect(deps).toEqual(jasmine.arrayContaining([ + jasmine.stringMatching(/\/template.html$/), + jasmine.stringMatching(/\/style.css$/), + ])); + }); + }); }); }); diff --git a/packages/compiler-cli/src/ngtsc/incremental/src/dependency_tracking.ts b/packages/compiler-cli/src/ngtsc/incremental/src/dependency_tracking.ts index e884aefbaa..42fc122f00 100644 --- a/packages/compiler-cli/src/ngtsc/incremental/src/dependency_tracking.ts +++ b/packages/compiler-cli/src/ngtsc/incremental/src/dependency_tracking.ts @@ -53,6 +53,12 @@ export class FileDependencyGraph i } } + getResourceDependencies(from: T): AbsoluteFsPath[] { + const node = this.nodes.get(from); + + return node ? [...node.usesResources] : []; + } + isStale(sf: T, changedTsPaths: Set, changedResources: Set): boolean { return isLogicallyChanged(sf, this.nodeFor(sf), changedTsPaths, EMPTY_SET, changedResources); }