Skip to content

Commit 3842157

Browse files
JeanMecheAndrewKushnir
authored andcommitted
feat(core): Make the isStandalone() function available in public API (#48114)
This commit updates an internal `isStandalone` function and exposes it as a public API, so that it can be used in applications code. fixes #47919 PR Close #48114
1 parent b4ab710 commit 3842157

7 files changed

Lines changed: 80 additions & 8 deletions

File tree

goldens/public-api/core/index.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,9 @@ export interface InputDecorator {
787787
// @public
788788
export function isDevMode(): boolean;
789789

790+
// @public
791+
export function isStandalone(type: Type<unknown>): boolean;
792+
790793
// @public
791794
export interface IterableChangeRecord<V> {
792795
readonly currentIndex: number | null;

packages/core/src/core.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export {SecurityContext} from './sanitization/security';
3838
export {Sanitizer} from './sanitization/sanitizer';
3939
export {createNgModule, createNgModuleRef, createEnvironmentInjector} from './render3/ng_module_ref';
4040
export {createComponent, reflectComponentType, ComponentMirror} from './render3/component';
41+
export {isStandalone} from './render3/definition';
4142

4243
import {global} from './util/global';
4344
if (typeof ngDevMode !== 'undefined' && ngDevMode) {

packages/core/src/core_render3_private_export.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,6 @@ export {
248248
export {
249249
compilePipe as ɵcompilePipe,
250250
} from './render3/jit/pipe';
251-
export { isStandalone as ɵisStandalone} from './render3/definition';
252251
export { Profiler as ɵProfiler, ProfilerEvent as ɵProfilerEvent } from './render3/profiler';
253252
export {
254253
publishDefaultGlobalUtils as ɵpublishDefaultGlobalUtils

packages/core/src/render3/definition.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
*/
88

99
import {ChangeDetectionStrategy} from '../change_detection/constants';
10-
import {NG_PROV_DEF} from '../di/interface/defs';
1110
import {Mutable, Type} from '../interface/type';
1211
import {NgModuleDef} from '../metadata/ng_module_def';
1312
import {SchemaMetadata} from '../metadata/schema';
@@ -741,7 +740,15 @@ export function getPipeDef<T>(type: any): PipeDef<T>|null {
741740
return type[NG_PIPE_DEF] || null;
742741
}
743742

744-
export function isStandalone<T>(type: Type<T>): boolean {
743+
/**
744+
* Checks whether a given Component, Directive or Pipe is marked as standalone.
745+
* This will return false if passed anything other than a Component, Directive, or Pipe class
746+
* See this guide for additional information: https://angular.io/guide/standalone-components
747+
*
748+
* @param type A reference to a Component, Directive or Pipe.
749+
* @publicApi
750+
*/
751+
export function isStandalone(type: Type<unknown>): boolean {
745752
const def = getComponentDef(type) || getDirectiveDef(type) || getPipeDef(type);
746753
return def !== null ? def.standalone : false;
747754
}

packages/core/src/render3/jit/module.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,7 @@ export function compileNgModuleDefs(
173173
Object.defineProperty(moduleType, NG_INJ_DEF, {
174174
get: () => {
175175
if (ngInjectorDef === null) {
176-
ngDevMode &&
177-
verifySemanticsOfNgModuleDef(
178-
moduleType as any as NgModuleType, allowDuplicateDeclarationsInRoot);
176+
ngDevMode && verifySemanticsOfNgModuleDef(moduleType, allowDuplicateDeclarationsInRoot);
179177
const meta: R3InjectorMetadataFacade = {
180178
name: moduleType.name,
181179
type: moduleType,

packages/core/test/acceptance/standalone_spec.ts

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

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

1313
describe('standalone components, directives, and pipes', () => {
@@ -847,4 +847,68 @@ describe('standalone components, directives, and pipes', () => {
847847
expect(fixture.nativeElement.textContent).toBe('');
848848
});
849849
});
850+
851+
describe('isStandalone()', () => {
852+
it('should return `true` if component is standalone', () => {
853+
@Component({selector: 'standalone-cmp', standalone: true})
854+
class StandaloneCmp {
855+
}
856+
857+
expect(isStandalone(StandaloneCmp)).toBeTrue();
858+
});
859+
860+
it('should return `false` if component is not standalone', () => {
861+
@Component({selector: 'standalone-cmp', standalone: false})
862+
class StandaloneCmp {
863+
}
864+
865+
expect(isStandalone(StandaloneCmp)).toBeFalse();
866+
});
867+
868+
it('should return `true` if directive is standalone', () => {
869+
@Directive({selector: '[standaloneDir]', standalone: true})
870+
class StandAloneDirective {
871+
}
872+
873+
expect(isStandalone(StandAloneDirective)).toBeTrue();
874+
});
875+
876+
it('should return `false` if directive is standalone', () => {
877+
@Directive({selector: '[standaloneDir]', standalone: false})
878+
class StandAloneDirective {
879+
}
880+
881+
expect(isStandalone(StandAloneDirective)).toBeFalse();
882+
});
883+
884+
it('should return `true` if pipe is standalone', () => {
885+
@Pipe({name: 'standalonePipe', standalone: true})
886+
class StandAlonePipe {
887+
}
888+
889+
expect(isStandalone(StandAlonePipe)).toBeTrue();
890+
});
891+
892+
it('should return `false` if pipe is standalone', () => {
893+
@Pipe({name: 'standalonePipe', standalone: false})
894+
class StandAlonePipe {
895+
}
896+
897+
expect(isStandalone(StandAlonePipe)).toBeFalse();
898+
});
899+
900+
it('should return `false` if the class is not annotated', () => {
901+
class NonAnnotatedClass {}
902+
903+
expect(isStandalone(NonAnnotatedClass)).toBeFalse();
904+
});
905+
906+
it('should return `false` if the class is an NgModule', () => {
907+
@NgModule({})
908+
class Module {
909+
}
910+
911+
expect(isStandalone(Module)).toBeFalse();
912+
});
913+
});
850914
});

packages/router/src/utils/config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {createEnvironmentInjector, EnvironmentInjector, Type, ɵisStandalone as isStandalone, ɵRuntimeError as RuntimeError} from '@angular/core';
9+
import {createEnvironmentInjector, EnvironmentInjector, isStandalone, Type, ɵRuntimeError as RuntimeError} from '@angular/core';
1010

1111
import {EmptyOutletComponent} from '../components/empty_outlet';
1212
import {RuntimeErrorCode} from '../errors';

0 commit comments

Comments
 (0)