Skip to content

Commit

Permalink
fix(core): Discard self-imports on standalone components.
Browse files Browse the repository at this point in the history
Before this fix, a self import would define the component twice in the `directiveRegistry` which would then fire a `NG0300` when compiled with the JIT.

fixes angular#50525
  • Loading branch information
JeanMeche committed Jun 2, 2023
1 parent 7e468df commit ed04c12
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 3 deletions.
5 changes: 3 additions & 2 deletions packages/core/src/render3/jit/directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,9 +242,10 @@ function getStandaloneDefFunctions(type: Type<any>, imports: Type<any>[]): {
let cachedPipeDefs: PipeDefList|null = null;
const directiveDefs = () => {
if (cachedDirectiveDefs === null) {
const selfDefinition = getComponentDef(type)!;
// Standalone components are always able to self-reference, so include the component's own
// definition in its `directiveDefs`.
cachedDirectiveDefs = [getComponentDef(type)!];
cachedDirectiveDefs = [selfDefinition];
const seen = new Set<Type<unknown>>();

for (const rawDep of imports) {
Expand All @@ -267,7 +268,7 @@ function getStandaloneDefFunctions(type: Type<any>, imports: Type<any>[]): {
}
} else {
const def = getComponentDef(dep) || getDirectiveDef(dep);
if (def) {
if (def && def !== selfDefinition) {
cachedDirectiveDefs.push(def);
}
}
Expand Down
23 changes: 22 additions & 1 deletion packages/core/test/acceptance/standalone_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/

import {CommonModule} from '@angular/common';
import {CommonModule, NgIf} from '@angular/common';
import {Component, createEnvironmentInjector, Directive, EnvironmentInjector, forwardRef, Injector, Input, isStandalone, NgModule, NO_ERRORS_SCHEMA, OnInit, Pipe, PipeTransform, ViewChild, ViewContainerRef} from '@angular/core';
import {TestBed} from '@angular/core/testing';

Expand Down Expand Up @@ -944,5 +944,26 @@ describe('standalone components, directives, and pipes', () => {
fixture.detectChanges();
expect(fixture.nativeElement.textContent).toBe('((A)B)C');
});

fit('should not throw if a standalone component imports itself', () => {
@Component({
selector: 'comp',
template: '<comp *ngIf="recurse"/>',
standalone: true,
imports: [Comp, NgIf]
})
class Comp {
@Input() recurse = false;
}

@Component({template: '<comp [recurse]="true"/>', standalone: true, imports: [Comp]})
class App {
}

expect(() => {
const fixture = TestBed.createComponent(App);
fixture.detectChanges();
}).not.toThrow();
});
});
});

0 comments on commit ed04c12

Please sign in to comment.