Skip to content

perf: deflate dts rollups by splitting published types out of framework type graphs - #237

Merged
antfu merged 1 commit into
mainfrom
plan-038-dts-deflation
Aug 15, 2026
Merged

perf: deflate dts rollups by splitting published types out of framework type graphs#237
antfu merged 1 commit into
mainfrom
plan-038-dts-deflation

Conversation

@antfubot

Copy link
Copy Markdown
Collaborator

Summary

Deflates two ~0.9 MB declaration rollups that inlined a full framework's type surface for the sake of a handful of published types.

@devframes/hub-ui

dist/index.d.mts was 939 KB — the node entry (createUi()) only publishes three config types (DevframeBranding, DevframeDockPreferences, EmbeddedVisibility), but they were previously defined inside client modules that import vue (./client/state/branding, in particular). tsdown's dts bundler followed that type chain and inlined Vue's entire runtime-core/reactivity declaration surface to describe them.

Fix: moved the three published types into a new Vue-free packages/hub-ui/src/types.ts, and flipped the import direction — the client modules (state/branding.ts, embedded/visibility.ts) now import their type from src/types.ts instead of the node entry importing from them. client/dock-preferences.ts (pure types, no other consumers) was folded directly into src/types.ts. No client module is reachable from the node entry's type graph anymore.

Result: dist/index.d.mts6.6 KB.

@devframes/plugin-messages

dist/client/index.d.mts was 935 KB. Diagnosis: unlike this package's other exports, useMessages() genuinely returns Reactive<MessagesState> — a real Vue reactivity type, not a documentation-only import (the panel is a Vue app; mountMessages() mounts it with createApp). Since vue wasn't marked external for this build, the dts bundler inlined Vue's whole reactivity/runtime-core surface just to spell out Reactive<T>.

This isn't the same pathology as hub-ui — it's a load-bearing framework type on a genuinely Vue-authored client entry, so relocating the type wouldn't help (Reactive<T> still has to come from vue either way). Per the plan's third option, I marked vue as deps.neverBundle on this build's dts-only config (dts: { emitDtsOnly: true }, so it has zero effect on JS output — the actual client bundle is still produced separately by the Vite lib build, with Vue inlined exactly as before). The declaration now references import('vue').Reactive<...> instead of inlining it.

Result: dist/client/index.d.mts2.1 KB.

Sibling sweep

find packages plugins -path '*/dist/*' -name '*.d.mts' -size +200k returns nothing after the fix — no other package exhibits this pathology (largest remaining is json-render-ui/dist/spa.d.mts at 122 KB, unrelated).

Verification

  • tsnapi API snapshots (pnpm test) pass unchanged — the public shape of both packages is identical, this is purely a build/packaging fix.
  • pnpm lint && pnpm knip && pnpm test && pnpm typecheck && pnpm build all pass (102 test files / 1132 tests, 30/30 typecheck tasks, 23/23 build tasks).

Note on plan location

This repo's plan-038-dts-deflation worktree was branched from a plan file that isn't present under this worktree's plans/ directory, so status is reported here instead of in plans/README.md per the task instructions.


Created with the help of an agent.

…rk type graphs

- hub-ui: move DevframeBranding/DevframeDockPreferences/EmbeddedVisibility
  into a Vue-free src/types.ts; client modules import from there instead of
  the node entry importing types from Vue-using client files. Drops
  dist/index.d.mts from 939 KB to 6.6 KB.
- plugin-messages: mark vue neverBundle on the client dts-only build so
  useMessages()'s Reactive<MessagesState> stays an import('vue') reference
  instead of inlining Vue's entire reactivity/runtime-core type surface.
  Drops dist/client/index.d.mts from 935 KB to 2.1 KB. No JS output change
  (useMessages genuinely returns a Vue-reactive value; the browser bundle
  is still built separately by Vite with vue inlined as before).
@netlify

netlify Bot commented Aug 15, 2026

Copy link
Copy Markdown

Deploy Preview for devfra ready!

Name Link
🔨 Latest commit a1f91db
🔍 Latest deploy log https://app.netlify.com/projects/devfra/deploys/6a8018a3e1e1fe000886c198
😎 Deploy Preview https://deploy-preview-237--devfra.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@antfu
antfu merged commit f471b6c into main Aug 15, 2026
12 checks passed
@antfu
antfu deleted the plan-038-dts-deflation branch August 15, 2026 07:45
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.

2 participants