Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Angular: Fix wrong detection of standalone components #27353

Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ const TestComponent1 = Component({})(class {});
const TestComponent2 = Component({})(class {});
const StandaloneTestComponent = Component({ standalone: true })(class {});
const StandaloneTestDirective = Directive({ standalone: true })(class {});
const MixedTestComponent1 = Component({ standalone: true })(
class extends StandaloneTestComponent {}
);
const MixedTestComponent2 = Component({})(class extends MixedTestComponent1 {});
const MixedTestComponent3 = Component({ standalone: true })(class extends MixedTestComponent2 {});
const TestModuleWithDeclarations = NgModule({ declarations: [TestComponent1] })(class {});
const TestModuleWithImportsAndProviders = NgModule({
imports: [TestModuleWithDeclarations],
Expand Down Expand Up @@ -152,6 +157,21 @@ describe('PropertyExtractor', () => {
const { isStandalone } = PropertyExtractor.analyzeDecorators(StandaloneTestComponent);
expect(isStandalone).toBe(true);
});

it('isStandalone should be true', () => {
const { isStandalone } = PropertyExtractor.analyzeDecorators(MixedTestComponent1);
expect(isStandalone).toBe(true);
});

it('isStandalone should be false', () => {
const { isStandalone } = PropertyExtractor.analyzeDecorators(MixedTestComponent2);
expect(isStandalone).toBe(false);
});

it('isStandalone should be true', () => {
const { isStandalone } = PropertyExtractor.analyzeDecorators(MixedTestComponent3);
expect(isStandalone).toBe(true);
});
});

describe('extractProviders', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,17 @@ export class PropertyExtractor implements NgModuleMetadata {
const isPipe = decorators.some((d) => this.isDecoratorInstanceOf(d, 'Pipe'));

const isDeclarable = isComponent || isDirective || isPipe;
const isStandalone = (isComponent || isDirective) && decorators.some((d) => d.standalone);

// Check if the hierarchically lowest Component or Directive decorator (the only relevant for importing dependencies) is standalone.
const isStandalone = !!(
(isComponent || isDirective) &&
[...decorators]
.reverse() // reflectionCapabilities returns decorators in a hierarchically top-down order
.find(
(d) =>
this.isDecoratorInstanceOf(d, 'Component') || this.isDecoratorInstanceOf(d, 'Directive')
)?.standalone
);

return { isDeclarable, isStandalone };
};
Expand Down