diff --git a/packages/compiler-cli/src/ngtsc/annotations/common/src/standalone-default-value.ts b/packages/compiler-cli/src/ngtsc/annotations/common/src/standalone-default-value.ts new file mode 100644 index 00000000000..70445ac6897 --- /dev/null +++ b/packages/compiler-cli/src/ngtsc/annotations/common/src/standalone-default-value.ts @@ -0,0 +1,13 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +/** + * A constant defining the default value for the standalone attribute in Directive and Pipes decorators. + * Extracted to a separate file to facilitate G3 patches. + */ +export const NG_STANDALONE_DEFAULT_VALUE = false; diff --git a/packages/compiler-cli/src/ngtsc/annotations/directive/src/shared.ts b/packages/compiler-cli/src/ngtsc/annotations/directive/src/shared.ts index 5778bc4ce66..a31b3e4f3f0 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/directive/src/shared.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/directive/src/shared.ts @@ -84,6 +84,7 @@ import {tryParseSignalInputMapping} from './input_function'; import {tryParseSignalModelMapping} from './model_function'; import {tryParseInitializerBasedOutput} from './output_function'; import {tryParseSignalQueryFromInitializer} from './query_functions'; +import {NG_STANDALONE_DEFAULT_VALUE} from '../../common/src/standalone-default-value'; const EMPTY_OBJECT: {[key: string]: string} = {}; @@ -335,7 +336,7 @@ export function extractDirectiveMetadata( dep.token.value.name === 'TemplateRef', ); - let isStandalone = false; + let isStandalone = NG_STANDALONE_DEFAULT_VALUE; if (directive.has('standalone')) { const expr = directive.get('standalone')!; const resolved = evaluator.evaluate(expr); diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/pipe.ts b/packages/compiler-cli/src/ngtsc/annotations/src/pipe.ts index 4b4e22b1305..a3793e4c5b2 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/pipe.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/pipe.ts @@ -49,6 +49,7 @@ import { unwrapExpression, wrapTypeReference, } from '../common'; +import {NG_STANDALONE_DEFAULT_VALUE} from '../common/src/standalone-default-value'; export interface PipeHandlerData { meta: R3PipeMetadata; @@ -176,7 +177,7 @@ export class PipeDecoratorHandler pure = pureValue; } - let isStandalone = false; + let isStandalone = NG_STANDALONE_DEFAULT_VALUE; if (pipe.has('standalone')) { const expr = pipe.get('standalone')!; const resolved = this.evaluator.evaluate(expr); diff --git a/packages/core/src/core_render3_private_export.ts b/packages/core/src/core_render3_private_export.ts index bd32889ec50..8a5acc65e3a 100644 --- a/packages/core/src/core_render3_private_export.ts +++ b/packages/core/src/core_render3_private_export.ts @@ -310,3 +310,4 @@ export { } from './render3/deps_tracker/deps_tracker'; export {generateStandaloneInDeclarationsError as ɵgenerateStandaloneInDeclarationsError} from './render3/jit/module'; export {getAsyncClassMetadataFn as ɵgetAsyncClassMetadataFn} from './render3/metadata'; +export {NG_STANDALONE_DEFAULT_VALUE as ɵNG_STANDALONE_DEFAULT_VALUE} from './render3/standalone-default-value'; diff --git a/packages/core/src/render3/jit/directive.ts b/packages/core/src/render3/jit/directive.ts index 31c8b4a9d53..c3125eaca9f 100644 --- a/packages/core/src/render3/jit/directive.ts +++ b/packages/core/src/render3/jit/directive.ts @@ -41,6 +41,7 @@ import { patchComponentDefWithScope, transitiveScopesFor, } from './module'; +import {NG_STANDALONE_DEFAULT_VALUE} from '../standalone-default-value'; import {isComponent, verifyStandaloneImport} from './util'; /** @@ -452,7 +453,8 @@ export function directiveMetadata(type: Type, metadata: Directive): R3Direc exportAs: extractExportAs(metadata.exportAs), providers: metadata.providers || null, viewQueries: extractQueriesMetadata(type, propMetadata, isViewQuery), - isStandalone: !!metadata.standalone, + isStandalone: + metadata.standalone === undefined ? NG_STANDALONE_DEFAULT_VALUE : !!metadata.standalone, isSignal: !!metadata.signals, hostDirectives: metadata.hostDirectives?.map((directive) => diff --git a/packages/core/src/render3/jit/pipe.ts b/packages/core/src/render3/jit/pipe.ts index a14db77496d..2563642e284 100644 --- a/packages/core/src/render3/jit/pipe.ts +++ b/packages/core/src/render3/jit/pipe.ts @@ -17,6 +17,7 @@ import {Pipe} from '../../metadata/directives'; import {NG_FACTORY_DEF, NG_PIPE_DEF} from '../fields'; import {angularCoreEnv} from './environment'; +import {NG_STANDALONE_DEFAULT_VALUE} from '../standalone-default-value'; export function compilePipe(type: Type, meta: Pipe): void { let ngPipeDef: any = null; @@ -73,6 +74,6 @@ function getPipeMetadata(type: Type, meta: Pipe): R3PipeMetadataFacade { name: type.name, pipeName: meta.name, pure: meta.pure !== undefined ? meta.pure : true, - isStandalone: !!meta.standalone, + isStandalone: meta.standalone === undefined ? NG_STANDALONE_DEFAULT_VALUE : !!meta.standalone, }; } diff --git a/packages/core/src/render3/standalone-default-value.ts b/packages/core/src/render3/standalone-default-value.ts new file mode 100644 index 00000000000..70445ac6897 --- /dev/null +++ b/packages/core/src/render3/standalone-default-value.ts @@ -0,0 +1,13 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +/** + * A constant defining the default value for the standalone attribute in Directive and Pipes decorators. + * Extracted to a separate file to facilitate G3 patches. + */ +export const NG_STANDALONE_DEFAULT_VALUE = false; diff --git a/packages/core/test/bundling/defer/bundle.golden_symbols.json b/packages/core/test/bundling/defer/bundle.golden_symbols.json index 8785214bb63..18c5e2acc9e 100644 --- a/packages/core/test/bundling/defer/bundle.golden_symbols.json +++ b/packages/core/test/bundling/defer/bundle.golden_symbols.json @@ -2003,6 +2003,9 @@ { "name": "init_skip_hydration" }, + { + "name": "init_standalone_default_value" + }, { "name": "init_standalone_feature" }, diff --git a/packages/core/testing/src/test_bed_compiler.ts b/packages/core/testing/src/test_bed_compiler.ts index 9ac579f7451..8e832d0c36d 100644 --- a/packages/core/testing/src/test_bed_compiler.ts +++ b/packages/core/testing/src/test_bed_compiler.ts @@ -65,6 +65,7 @@ import { ɵɵInjectableDeclaration as InjectableDeclaration, NgZone, ErrorHandler, + ɵNG_STANDALONE_DEFAULT_VALUE as NG_STANDALONE_DEFAULT_VALUE, } from '@angular/core'; import {ComponentDef, ComponentType} from '../../src/render3'; @@ -102,7 +103,7 @@ function assertNoStandaloneComponents( types.forEach((type) => { if (!getAsyncClassMetadataFn(type)) { const component = resolver.resolve(type); - if (component && component.standalone) { + if (component && (component.standalone ?? NG_STANDALONE_DEFAULT_VALUE)) { throw new Error(ɵgenerateStandaloneInDeclarationsError(type, location)); } }