Skip to content

fix(defer): support named deferredImports blocks (Angular 22.2) - #669

Merged
Brooooooklyn merged 3 commits into
mainfrom
fix/deferred-imports-named
Nov 2, 2026
Merged

Brooooooklyn merged 3 commits into
mainfrom
fix/deferred-imports-named

Conversation

@Brooooooklyn

Copy link
Copy Markdown
Member

Closes #654

Angular 22.2 changed @Component.deferredImports to an object that maps block names to classes, picked with @defer (name blk). OXC failed with Unrecognized trigger, and read only the old array form.

What changed

@defer (name blk)          → parser stores the block name (22.2.0-next.4+)
deferredImports: {blk:[A]} → a list per block
   ├─ full    → App_Defer_N_DepsFn per block (blocks with the same list share one)
   ├─ partial → deferBlockDependencies: [...] (outer block first)
   └─ linker  → links these files (before: left ɵɵngDeclareComponent unlinked, no error)
Case Before Now (matches ngtsc 22.2.3)
Named blocks, nested blocks, name before/after triggers Unrecognized trigger per-block deps in full, partial, linked output
imports:[C] + named block using C error C stays eager (named form defers no imports entry)
ns.X in a block list — read eagerly: () => [ns.X]
@defer without name / unknown name / name without deferredImports no error ngtsc's errors (11100 / 11101 / 11102)
Array form on 22.2.0-next.5+ accepted error 1010
Object form before 22.2 ignored 'deferredImports' must be an array ...
Array form (≤ 22.1), partial no deferBlockDependencies emitted: every block gets the array's classes
Static import of a deferred class kept removed when deferredImports is the file's only use of it

name parse errors use Angular's text: Cannot specify multiple name parameters, Block names cannot be quoted in @defer blocks, Invalid block name "...".

Version gate

angularVersion Array form Object form name
< 22.2.0-next.4 ✅ error Unrecognized trigger
22.2.0-next.4 ✅ ✅ ✅
≥ 22.2.0-next.5, or unset error 1010 ✅ ✅

⚠️ The Vite plugin passes angularVersion only when the user sets it. So a project on Angular ≤ 22.1 that uses deferredImports: [A] and does not set angularVersion now gets error 1010. Unset means "latest", the same as the other version gates.

Known differences from ngtsc (not changed here)

  • Each block loads its declared list, in declared order (like ngtsc local mode). ngtsc full keeps only what the block uses, directives first. The runtime gets the same classes.
  • An import line with other uses in the file is kept silently. ngtsc reports 8014 there.
  • 8013 / 8012 (deferred class used outside @defer) and 2010 (not standalone) are not checked.
  • A non-literal deferredImports: CONST is not evaluated; a named block then gives 11102, like ngtsc local mode.
  • Under HMR or JIT the static import stays.

Verification

  • Case matrix compiled with ngtsc 22.2.3 (full / partial / local) and with OXC. Linked output checked against Angular's linker.
  • New tests/deferred_imports_named_test.rs (21 tests). Old array-form tests now set angularVersion 22.1.
  • cargo test with and without --all-features, conformance 1264/1264, napi pnpm test 419/419, pnpm check.

🤖 Generated with Claude Code

Brooooooklyn and others added 2 commits November 2, 2026 15:15
Angular 22.2 changed `@Component.deferredImports` to an object that maps
block names to classes, picked with `@defer (name blk)`. OXC failed with
"Unrecognized trigger" and read only the array form.

- Parse the `name` parameter with Angular's errors (22.2.0-next.4+).
- Read the object form; each named block gets its own dependency
  function in full mode and its own `deferBlockDependencies` entry in
  partial mode. The linker now links these blocks too.
- Report ngtsc's errors: missing `name`, unknown block, `name` without
  `deferredImports`, array form on 22.2.0-next.5+, object form before.
- Array form (before 22.2): partial mode now emits
  `deferBlockDependencies`, so linked blocks load their classes.
- Remove the static import of a class `@defer` loads, when
  `deferredImports` is the only place the file names it.

Closes #654

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ngtsc can't lazy-load a namespace member and gives the block
`() => [i1.X]`. OXC dropped the entry, so the block loaded nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Brooooooklyn

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-02T07:42:13.488600Z 0eb5fc8 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2f63f00c3a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

…able

With block names, a component defers no `imports` entry, so its entries
stay static references. The file-wide prepass still counted them, and
another component in the file could remove an import the first one
still used.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Brooooooklyn

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

Reviewed commit: 0eb5fc8f31

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@Brooooooklyn
Brooooooklyn merged commit b179ed1 into main Nov 2, 2026
10 checks passed
@Brooooooklyn
Brooooooklyn deleted the fix/deferred-imports-named branch November 2, 2026 13:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

deferredImports: partial output never loads the block, and the Angular 22.2 named form does not compile

1 participant