refactor(core): Tree shake the SimpleChanges & co.

Any application that doesn't use the `ngOnChanges` hook shouldn't pull its code.
This commit is contained in:
Matthieu Riegler
2026-04-12 17:03:21 +02:00
committed by Kirill Cherkashin
parent 63c7ac325d
commit 4744bab38e
10 changed files with 30 additions and 39 deletions
@@ -14,6 +14,8 @@ import {EMPTY_OBJ} from '../../util/empty';
import {applyValueToInputField} from '../apply_value_input_field';
import {DirectiveDef, DirectiveDefFeature} from '../interfaces/definition';
let _ngOnChangesFeatureImpl: typeof NgOnChangesFeatureImpl | null = null;
/**
* The NgOnChangesFeature decorates a component with support for the ngOnChanges
* lifecycle hook, so it should be included in any component that implements
@@ -37,6 +39,7 @@ import {DirectiveDef, DirectiveDefFeature} from '../interfaces/definition';
* @codeGenApi
*/
export const ɵɵNgOnChangesFeature: () => DirectiveDefFeature = /* @__PURE__ */ (() => {
_ngOnChangesFeatureImpl = NgOnChangesFeatureImpl;
const ɵɵNgOnChangesFeatureImpl = () => NgOnChangesFeatureImpl;
// This option ensures that the ngOnChanges lifecycle hook will be inherited
@@ -47,7 +50,14 @@ export const ɵɵNgOnChangesFeature: () => DirectiveDefFeature = /* @__PURE__ */
return ɵɵNgOnChangesFeatureImpl;
})();
export function NgOnChangesFeatureImpl<T>(definition: DirectiveDef<T>) {
export function getNgOnChangesFeatureImpl(): typeof NgOnChangesFeatureImpl {
return _ngOnChangesFeatureImpl!;
}
/**
* We don't expose the feature implementation directly in order to tree shake it when `ngOnChanges` isn't used.
*/
function NgOnChangesFeatureImpl<T>(definition: DirectiveDef<T>) {
if (definition.type.prototype.ngOnChanges) {
definition.setInput = ngOnChangesSetInput;
}
+3 -3
View File
@@ -20,8 +20,9 @@ import {
} from '../change_detection/lifecycle_hooks';
import {assertDefined, assertEqual, assertNotEqual} from '../util/assert';
import {ProfilerEvent} from '../../primitives/devtools';
import {assertFirstCreatePass} from './assert';
import {NgOnChangesFeatureImpl} from './features/ng_onchanges_feature';
import {getNgOnChangesFeatureImpl} from './features/ng_onchanges_feature';
import {DirectiveDef} from './interfaces/definition';
import {TNode} from './interfaces/node';
import {
@@ -35,7 +36,6 @@ import {
TView,
} from './interfaces/view';
import {profiler} from './profiler';
import {ProfilerEvent} from '../../primitives/devtools';
import {isInCheckNoChangesMode} from './state';
/**
@@ -61,7 +61,7 @@ export function registerPreOrderHooks(
DoCheck;
if (ngOnChanges as Function | undefined) {
const wrappedOnChanges = NgOnChangesFeatureImpl(directiveDef);
const wrappedOnChanges = getNgOnChangesFeatureImpl()(directiveDef);
(tView.preOrderHooks ??= []).push(directiveIndex, wrappedOnChanges);
(tView.preOrderCheckHooks ??= []).push(directiveIndex, wrappedOnChanges);
}
@@ -172,7 +172,6 @@
"NULL_REMOVAL_STATE",
"NULL_REMOVED_QUERIED_STATE",
"NgModuleRef",
"NgOnChangesFeatureImpl",
"NgZone",
"NodeInjector",
"NodeInjectorDestroyRef",
@@ -224,7 +223,6 @@
"SHARED_ANIMATION_PROVIDERS",
"SHARED_STYLES_HOST",
"SIGNAL",
"SIMPLE_CHANGES_STORE",
"STABILITY_WARNING_THRESHOLD",
"STAR_CLASSNAME",
"STAR_SELECTOR",
@@ -235,7 +233,6 @@
"Sanitizer",
"ShadowDomRenderer",
"SharedStylesHost",
"SimpleChange",
"SpecialCasedStyles",
"StandaloneService",
"StateValue",
@@ -309,6 +306,7 @@
"_isRefreshingViews",
"_keyMap",
"_locateOrCreateElementNode",
"_ngOnChangesFeatureImpl",
"_platformInjector",
"_processI18nInsertBefore",
"_retrieveHydrationInfoImpl",
@@ -525,6 +523,7 @@
"getNearestLContainer",
"getNextLContainer",
"getNgDirectiveDef",
"getNgOnChangesFeatureImpl",
"getNodeInjectable",
"getNullInjector",
"getOrBorrowReactiveLViewConsumer",
@@ -548,7 +547,6 @@
"getRuntimeErrorCode",
"getSelectedIndex",
"getSelectedTNode",
"getSimpleChangesStore",
"getStyleHost",
"getTNode",
"getTNodeFromLView",
@@ -706,7 +704,6 @@
"nextBindingIndex",
"nextNgElementId",
"nextNotification",
"ngOnChangesSetInput",
"ngZoneInstanceId",
"noSideEffects",
"noop",
@@ -763,7 +760,6 @@
"registerPostOrderHooks",
"registerPreOrderHooks",
"relativePath",
"rememberChangeHistoryAndInvokeOnChangesHook",
"remove",
"removeAnimationsFromQueue",
"removeClass",
@@ -821,7 +817,6 @@
"setRootDomAdapter",
"setSelectedIndex",
"setShadowStylingInputFlags",
"setSimpleChangesStore",
"setStyles",
"setThrowInvalidWriteToSignalError",
"setUpAttributes",
@@ -130,7 +130,6 @@
"NO_PARENT_INJECTOR",
"NULL_INJECTOR",
"NgModuleRef",
"NgOnChangesFeatureImpl",
"NgZone",
"NodeInjector",
"NodeInjectorDestroyRef",
@@ -172,14 +171,12 @@
"SHARED_STYLES_HOST",
"SIGNAL",
"SIGNAL_NODE",
"SIMPLE_CHANGES_STORE",
"STABILITY_WARNING_THRESHOLD",
"SVG_NAMESPACE",
"SafeSubscriber",
"Sanitizer",
"ShadowDomRenderer",
"SharedStylesHost",
"SimpleChange",
"StandaloneService",
"Subject",
"Subscriber",
@@ -235,6 +232,7 @@
"_keyMap",
"_locateOrCreateAnchorNode",
"_locateOrCreateTextNode",
"_ngOnChangesFeatureImpl",
"_platformInjector",
"_processI18nInsertBefore",
"_retrieveHydrationInfoImpl",
@@ -429,6 +427,7 @@
"getNearestLContainer",
"getNextLContainer",
"getNgDirectiveDef",
"getNgOnChangesFeatureImpl",
"getNodeInjectable",
"getNullInjector",
"getOrBorrowReactiveLViewConsumer",
@@ -453,7 +452,6 @@
"getRuntimeErrorCode",
"getSelectedIndex",
"getSelectedTNode",
"getSimpleChangesStore",
"getStyleHost",
"getTNode",
"getTNodeFromLView",
@@ -584,7 +582,6 @@
"nextBindingIndex",
"nextNgElementId",
"nextNotification",
"ngOnChangesSetInput",
"ngZoneInstanceId",
"noSideEffects",
"noop",
@@ -627,7 +624,6 @@
"registerPostOrderHooks",
"registerPreOrderHooks",
"relativePath",
"rememberChangeHistoryAndInvokeOnChangesHook",
"remove",
"removeAnimationsFromQueue",
"removeElements",
@@ -674,7 +670,6 @@
"setRootDomAdapter",
"setSelectedIndex",
"setShadowStylingInputFlags",
"setSimpleChangesStore",
"setThrowInvalidWriteToSignalError",
"setUpAttributes",
"setupHostDirectiveInputsOrOutputs",
@@ -176,7 +176,6 @@
"NO_PARENT_INJECTOR",
"NULL_INJECTOR",
"NgModuleRef",
"NgOnChangesFeatureImpl",
"NgZone",
"NodeInjector",
"NodeInjectorDestroyRef",
@@ -213,14 +212,12 @@
"SCHEDULE_IN_ROOT_ZONE_DEFAULT",
"SHARED_STYLES_HOST",
"SIGNAL",
"SIMPLE_CHANGES_STORE",
"SSR_BLOCK_STATE",
"SSR_UNIQUE_ID",
"STABILITY_WARNING_THRESHOLD",
"SVG_NAMESPACE",
"SafeSubscriber",
"Sanitizer",
"SimpleChange",
"StandaloneService",
"Subject",
"Subscriber",
@@ -279,6 +276,7 @@
"_locateOrCreateContainerAnchor",
"_locateOrCreateElementNode",
"_locateOrCreateTextNode",
"_ngOnChangesFeatureImpl",
"_platformInjector",
"_populateDehydratedViewsInLContainer",
"_processI18nInsertBefore",
@@ -475,6 +473,7 @@
"getNearestLContainer",
"getNextLContainer",
"getNgDirectiveDef",
"getNgOnChangesFeatureImpl",
"getNodeInjectable",
"getNullInjector",
"getOrBorrowReactiveLViewConsumer",
@@ -498,7 +497,6 @@
"getRuntimeErrorCode",
"getSelectedIndex",
"getSelectedTNode",
"getSimpleChangesStore",
"getStyleHost",
"getTDeferBlockDetails",
"getTNode",
@@ -626,7 +624,6 @@
"nextBindingIndex",
"nextNgElementId",
"nextNotification",
"ngOnChangesSetInput",
"ngZoneInstanceId",
"noSideEffects",
"noop",
@@ -663,7 +660,6 @@
"registerLView",
"registerPostOrderHooks",
"registerPreOrderHooks",
"rememberChangeHistoryAndInvokeOnChangesHook",
"remove",
"removeAnimationsFromQueue",
"removeFromArray",
@@ -714,7 +710,6 @@
"setLocaleId",
"setSelectedIndex",
"setShadowStylingInputFlags",
"setSimpleChangesStore",
"setTDeferBlockDetails",
"setThrowInvalidWriteToSignalError",
"setUpAttributes",
@@ -349,6 +349,7 @@
"_locateOrCreateElementNode",
"_locateOrCreateTextNode",
"_moduleDoBootstrap",
"_ngOnChangesFeatureImpl",
"_platformInjector",
"_populateDehydratedViewsInLContainer",
"_processI18nInsertBefore",
@@ -620,6 +621,7 @@
"getNextLContainer",
"getNgDirectiveDef",
"getNgModuleDef",
"getNgOnChangesFeatureImpl",
"getNodeInjectable",
"getNullInjector",
"getOrBorrowReactiveLViewConsumer",
@@ -350,6 +350,7 @@
"_locateOrCreateElementNode",
"_locateOrCreateTextNode",
"_moduleDoBootstrap",
"_ngOnChangesFeatureImpl",
"_platformInjector",
"_populateDehydratedViewsInLContainer",
"_processI18nInsertBefore",
@@ -616,6 +617,7 @@
"getNextLContainer",
"getNgDirectiveDef",
"getNgModuleDef",
"getNgOnChangesFeatureImpl",
"getNodeInjectable",
"getNullInjector",
"getOrBorrowReactiveLViewConsumer",
@@ -198,7 +198,6 @@
"NULL_INJECTOR",
"NUM_ROOT_NODES",
"NgModuleRef",
"NgOnChangesFeatureImpl",
"NgZone",
"NodeInjector",
"NodeInjectorDestroyRef",
@@ -250,7 +249,6 @@
"SHA256_ROUND_CONSTANTS",
"SHARED_STYLES_HOST",
"SIGNAL",
"SIMPLE_CHANGES_STORE",
"SKIP_HYDRATION_ATTR_NAME",
"SKIP_HYDRATION_ATTR_NAME_LOWER_CASE",
"SSR_BLOCK_STATE",
@@ -263,7 +261,6 @@
"Sanitizer",
"ShadowDomRenderer",
"SharedStylesHost",
"SimpleChange",
"StandaloneService",
"Subject",
"Subscriber",
@@ -337,6 +334,7 @@
"_locateOrCreateElementContainerNode",
"_locateOrCreateElementNode",
"_locateOrCreateTextNode",
"_ngOnChangesFeatureImpl",
"_platformInjector",
"_populateDehydratedViewsInLContainer",
"_processI18nInsertBefore",
@@ -597,6 +595,7 @@
"getNextLContainer",
"getNgContainerSize",
"getNgDirectiveDef",
"getNgOnChangesFeatureImpl",
"getNoOffsetIndex",
"getNodeInjectable",
"getNullInjector",
@@ -626,7 +625,6 @@
"getSegmentHead",
"getSelectedIndex",
"getSerializedContainerViews",
"getSimpleChangesStore",
"getStyleHost",
"getSymbolIterator",
"getTDeferBlockDetails",
@@ -793,7 +791,6 @@
"nextNgElementId",
"nextNotification",
"nextRender",
"ngOnChangesSetInput",
"ngZoneInstanceId",
"noSideEffects",
"noop",
@@ -849,7 +846,6 @@
"registerPostOrderHooks",
"registerPreOrderHooks",
"relativePath",
"rememberChangeHistoryAndInvokeOnChangesHook",
"remove",
"removeAllEventListeners",
"removeAnimationsFromQueue",
@@ -926,7 +922,6 @@
"setSegmentHead",
"setSelectedIndex",
"setShadowStylingInputFlags",
"setSimpleChangesStore",
"setStashFn",
"setTargetElement",
"setThrowInvalidWriteToSignalError",
@@ -381,6 +381,7 @@
"_locateOrCreateAnchorNode",
"_locateOrCreateElementNode",
"_locateOrCreateTextNode",
"_ngOnChangesFeatureImpl",
"_platformInjector",
"_processI18nInsertBefore",
"_retrieveHydrationInfoImpl",
@@ -694,6 +695,7 @@
"getNextLContainer",
"getNgDirectiveDef",
"getNgModuleDef",
"getNgOnChangesFeatureImpl",
"getNodeInjectable",
"getNullInjector",
"getOrBorrowReactiveLViewConsumer",
@@ -125,7 +125,6 @@
"NO_PARENT_INJECTOR",
"NULL_INJECTOR",
"NgModuleRef",
"NgOnChangesFeatureImpl",
"NgZone",
"NodeInjector",
"NodeInjectorDestroyRef",
@@ -163,14 +162,12 @@
"SCHEDULE_IN_ROOT_ZONE_DEFAULT",
"SHARED_STYLES_HOST",
"SIGNAL",
"SIMPLE_CHANGES_STORE",
"STABILITY_WARNING_THRESHOLD",
"SVG_NAMESPACE",
"SafeSubscriber",
"Sanitizer",
"ShadowDomRenderer",
"SharedStylesHost",
"SimpleChange",
"StandaloneService",
"Subject",
"Subscriber",
@@ -220,6 +217,7 @@
"_isRefreshingViews",
"_keyMap",
"_locateOrCreateTextNode",
"_ngOnChangesFeatureImpl",
"_platformInjector",
"_processI18nInsertBefore",
"_retrieveHydrationInfoImpl",
@@ -394,6 +392,7 @@
"getNearestLContainer",
"getNextLContainer",
"getNgDirectiveDef",
"getNgOnChangesFeatureImpl",
"getNodeInjectable",
"getNullInjector",
"getOrBorrowReactiveLViewConsumer",
@@ -414,7 +413,6 @@
"getRootTViewTemplate",
"getRuntimeErrorCode",
"getSelectedIndex",
"getSimpleChangesStore",
"getStyleHost",
"getTNode",
"getTNodeFromLView",
@@ -521,7 +519,6 @@
"nativeRemoveNode",
"nextNgElementId",
"nextNotification",
"ngOnChangesSetInput",
"ngZoneInstanceId",
"noSideEffects",
"noop",
@@ -559,7 +556,6 @@
"registerPostOrderHooks",
"registerPreOrderHooks",
"relativePath",
"rememberChangeHistoryAndInvokeOnChangesHook",
"remove",
"removeAnimationsFromQueue",
"removeElements",
@@ -604,7 +600,6 @@
"setRootDomAdapter",
"setSelectedIndex",
"setShadowStylingInputFlags",
"setSimpleChangesStore",
"setThrowInvalidWriteToSignalError",
"setUpAttributes",
"setupHostDirectiveInputsOrOutputs",