When `@Component.deferredImports` maps blocks to arrays of dependencies, an explicitly
deferred dependency might be defined in multiple blocks (e.g. `block1: [CmpA], block2: [CmpA]`).
Previously, these were appended to the `explicitlyDeferredTypes` array without deduplication.
When generating the `setClassMetadataAsync` wrapper for development mode, the compiler
used this array to generate callback parameters for dynamic imports. This resulted in
duplicate parameter names in the callback signature `(CmpA, CmpA) => { ... }`, which
causes an `Uncaught SyntaxError` when V8 parses the module in strict mode.
This commit deduplicates `explicitlyDeferredTypes` in the `ngtsc` component handler, and
adds a secondary deduplication check in the `r3_class_metadata_compiler` generator to
ensure duplicate parameter names are never emitted.
When `onlyExplicitDeferDependencyImports` is enabled, dependencies that are used exclusively inside a `@defer` block but are provided eagerly (i.e., in the `imports` array but omitted from `deferredImports`) were incorrectly dropped from the generated `dependencies` array.
This occurred because the template binder intentionally omits directives used only inside defer blocks from the eager directives list, and the defer block resolver only tracks dependencies explicitly listed in `deferredImports`.
This commit fixes the issue by ensuring that any template dependency used within a defer block that is not deferred is explicitly preserved as an eager dependency, ensuring it is available at runtime.
When @Component.deferredImports is defined as an object mapping block
names to dependency arrays, deduplicate entries when aggregating block
imports into the component-level flattened scope. This prevents
duplicate directive/component collisions in DirectiveMatcher when
multiple @defer blocks share dependencies.
Enforces that components, directives, and pipes in @Component.deferredImports mapped to specific block keys are only used within their designated @defer blocks during template type checking, reporting out-of-band diagnostics when used eagerly or across mismatched blocks.
Allow `@Component.deferredImports` to be an object mapping block names to arrays of dependencies, and support `@defer (name blockName)` syntax to configure block-specific dependency lists in both standard and local compilation modes.
This enables more targeted dependency chunk generation during local compilation instead of over-eagerly loading all deferred imports together.
This commit updates `@defer` logic related to incremental hydration to be tree-shakable.
If hydrate triggers are used in a `@defer` block, the compiler emits a single top-level call to `ɵɵenableIncrementalHydrationRuntime`, placed once per create block before the first `ɵɵdefer` that requires it.
As a result, the incremental hydration runtime is only included in the bundle when hydrate is explicitly used.
In some cases the `debugName` transform generates a spread into the signal function parameters. This can cause compiler errors, because the functions don't have rest parameters.
These changes work around it by adding a `@ts-ignore` above it.
When defer blocks have a reference-based trigger without a parameter, we infer it from the placeholder block. This requires some validations like ensuring that there's only one element in the placeholder. The validations are currently implemented at the parser level which can affect tools like linters that need to pass `preserveWhitespaces: true` in order to get accurate source mappings.
These changes move the validations into the template type checker so that they still get flagged, but much later in the process. Moving them over involves a bit more work, because the template type checker also sets `preserveWhitespaces: true`.
Fixes#61725.
PR Close#61747
Currently we don't defer any symbols that have references outside of the `import` statement and the `imports` array. This is a bit too aggressive, because it's possible that the symbol is only used for types (e.g. `viewChild<SomeCmp>('ref')`) which will be stripped when emitting to JS.
These changes expand the logic so that references inside type nodes aren't considered.
**Note:** one special case is when the symbol used in constructor-based DI (e.g. `constructor(someCmp: SomeCmp)`, because these constructors will be compiled to `directiveInject` calls. We don't need to worry about them, because the compiler introduces an addition `import * as i1 from './some-cmp';` import that it uses to refer to the symbol.
Fixes#55991.
PR Close#58104
This commit replaces `fake_core` with the real `@angular/core`
output. See previous commit for reasons.
Overall, this commit:
* Replaces references of `fake_core`
* Fixes tests that were testing Angular compiler detection that _would_
already be flagged by type-checking of TS directly. We keep these
tests for now, and add `@ts-ignore` to verify the Angular checks, in
case type checking is disabled in user applications- but it's worth
considering to remove these tests. Follow-up question/non-priority.
* Adds `@ts-ignore` to the tests for `defer` 1P because the property is
marked as `@internal` and now is (correctly) causing failures in the
compiler test environment.
* Fixes a couple of tests with typos, wrong properties etc that
previously weren't detected! A good sign.
PR Close#54650