Skip to content

feat(vite): augment library .d.ts with Ivy type declarations (#104)#341

Merged
brandonroberts merged 2 commits into
mainfrom
feat/library-dts-plugin-104
Jun 8, 2026
Merged

feat(vite): augment library .d.ts with Ivy type declarations (#104)#341
brandonroberts merged 2 commits into
mainfrom
feat/library-dts-plugin-104

Conversation

@brandonroberts

@brandonroberts brandonroberts commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

Summary

Closes #104 — library .d.ts support at the plugin layer.

When building an Angular library with compilationMode: 'partial', the plugin now augments the emitted .d.ts with Angular's Ivy type declarations (static ɵfac, static ɵcmp, …) so downstream consumers get full template type-checking against the published library.

The compiler already returns these per-class members on the transform result (dtsDeclarations, added in #86/#101); this PR wires them through the Vite plugin.

How it works

  • During transform (partial mode only), result.dtsDeclarations are collected, keyed by class name.
  • A new dtsPlugin (enforce: 'post') runs in generateBundle, after the user's declaration generator has emitted its .d.ts assets, and splices the members into the matching classes — adding import * as i0 from "@angular/core" where needed.
  • It is a no-op outside compilationMode: 'partial'.

The plugin does not generate the base .d.ts itself — a declaration generator (rolldown-plugin-dts, vite-plugin-dts, tsdown, or tsc) produces them; we augment them.

// Angular library build
import { angular } from '@oxc-angular/vite'
import dts from 'rolldown-plugin-dts'

export default defineConfig({
  plugins: [angular({ compilationMode: 'partial' }), dts()],
  build: { lib: { entry: 'src/public-api.ts', formats: ['es'] } },
})

Changes

  • vite-plugin/utils/dts.tsinjectDtsDeclarations injector (idempotent; skips unmatched classes; preserves leading triple-slash refs).
  • vite-plugin/index.ts — collect declarations during transform; new post-enforce dtsPlugin augmenting .d.ts bundle assets.
  • test/dts.test.ts — 7 tests, including an end-to-end run through the real Rust compiler.
  • README.md — "Library builds (.d.ts)" section.

Notes

  • TS-only — no native rebuild required.
  • Full suite passes (200/200); new file lints/formats clean (oxfmt, oxlint).

🤖 Generated with Claude Code

Library builds (`compilationMode: 'partial'`) now emit Angular's Ivy
`.d.ts` type declarations (`static ɵfac`, `static ɵcmp`, …) so consumers
get full template type-checking against a published library.

The compiler already returns these per-class members on the transform
result (`dtsDeclarations`); this wires them through the Vite plugin. A
new post-enforce `dtsPlugin` collects declarations during `transform`
and, in `generateBundle`, splices them into the `.d.ts` assets emitted
by a separate declaration generator (rolldown-plugin-dts, vite-plugin-dts,
tsdown, tsc), adding the required `import * as i0 from "@angular/core"`.

The plugin does not generate the base `.d.ts` itself — it augments
existing ones. No-op outside partial mode.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Brooooooklyn

Copy link
Copy Markdown
Member

@codex review

@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: b97478d13d

ℹ️ 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".

Comment thread napi/angular-compiler/vite-plugin/index.ts Outdated
Key the collected Ivy `.d.ts` declarations by module id instead of class
name so `vite build --watch` can drop a module's prior entries before
re-transforming it. Eviction runs ahead of the quick decorator early-return,
so removing a decorator no longer leaves stale `ɵfac`/`ɵcmp` metadata to be
re-injected into a now-plain class. generateBundle flattens module entries
into a class-name map (last write wins), matching prior behavior.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@brandonroberts brandonroberts enabled auto-merge (squash) June 8, 2026 13:20
@brandonroberts brandonroberts merged commit c760d4d into main Jun 8, 2026
9 checks passed
@brandonroberts brandonroberts deleted the feat/library-dts-plugin-104 branch June 8, 2026 14:27
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.

Expose .d.ts library build support at the plugin layer

2 participants