Skip to content

Commit 408af24

Browse files
crisbetoAndrewKushnir
authored andcommittedJan 21, 2025
fix(core): capture self-referencing component during HMR (#59644)
Fixes that we were filtering out the component itself from the set of dependencies when HMR is enabled, breaking self-referencing components. Fixes #59632. PR Close #59644
1 parent d7575c2 commit 408af24

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed
 

‎packages/compiler-cli/src/ngtsc/annotations/component/src/handler.ts

+5
Original file line numberDiff line numberDiff line change
@@ -1229,6 +1229,11 @@ export class ComponentDecoratorHandler
12291229
for (const dep of dependencies) {
12301230
if (dep.ref.node !== node) {
12311231
eagerlyUsed.add(dep.ref.node);
1232+
} else {
1233+
const used = bound.getEagerlyUsedDirectives();
1234+
if (used.some((current) => current.ref.node === node)) {
1235+
eagerlyUsed.add(node);
1236+
}
12321237
}
12331238
}
12341239
} else {

‎packages/compiler-cli/test/ngtsc/hmr_spec.ts

+46
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,52 @@ runInEachFileSystem(() => {
405405
expect(hmrContents).toBe(null);
406406
});
407407

408+
it('should capture self-referencing component during HMR', () => {
409+
enableHmr();
410+
env.write(
411+
'test.ts',
412+
`
413+
import {Component} from '@angular/core';
414+
415+
@Component({selector: 'cmp', template: '<cmp/>',})
416+
export class Cmp {}
417+
`,
418+
);
419+
420+
env.driveMain();
421+
422+
const jsContents = env.getContents('test.js');
423+
const hmrContents = env.driveHmr('test.ts', 'Cmp');
424+
expect(jsContents).toContain('dependencies: [Cmp]');
425+
expect(jsContents).toContain('ɵɵreplaceMetadata(Cmp, m.default, [i0], [Component]));');
426+
expect(hmrContents).toContain(
427+
'export default function Cmp_UpdateMetadata(Cmp, ɵɵnamespaces, Component) {',
428+
);
429+
});
430+
431+
it('should capture component in its own dependencies if it is not used in the template', () => {
432+
enableHmr();
433+
env.write(
434+
'test.ts',
435+
`
436+
import {Component} from '@angular/core';
437+
438+
@Component({selector: 'cmp', template: ''})
439+
export class Cmp {}
440+
`,
441+
);
442+
443+
env.driveMain();
444+
445+
const jsContents = env.getContents('test.js');
446+
const hmrContents = env.driveHmr('test.ts', 'Cmp');
447+
expect(jsContents).not.toContain('dependencies');
448+
expect(jsContents).toContain('ɵɵreplaceMetadata(Cmp, m.default, [i0], [Component]));');
449+
expect(hmrContents).toContain(
450+
'export default function Cmp_UpdateMetadata(Cmp, ɵɵnamespaces, Component) {',
451+
);
452+
});
453+
408454
it('should capture shorthand property assignment dependencies', () => {
409455
enableHmr();
410456
env.write(

0 commit comments

Comments
 (0)
Please sign in to comment.