Skip to content

fix(packaging): declare @dnd-kit/utilities peer, add ./announcements subpath export - #25

Merged
KruGoL merged 2 commits into
mainfrom
fix/announcements-subpath-export
Aug 4, 2026
Merged

fix(packaging): declare @dnd-kit/utilities peer, add ./announcements subpath export#25
KruGoL merged 2 commits into
mainfrom
fix/announcements-subpath-export

Conversation

@KruGoL

@KruGoL KruGoL commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

The defect

0.1.38's main bundle dist/index.js statically imports four bare specifiers that a consumer must provide: @tanstack/react-table, @dnd-kit/core, @dnd-kit/sortable and @dnd-kit/utilities. All four are in tsup.config.ts's external array; only three are declared in peerDependencies.

@dnd-kit/utilities was declared nowhere — not in dependencies, not in peerDependencies. The package imported a specifier it never asked anyone to install. It only ever resolved because every consumer so far happened to depend on it directly.

The failure surfaced when sphere-quest-frontend switched from a local file: link to the published package. That app uses only the announcement components and carries none of the table/drag-and-drop stack:

Error: [vite]: Rolldown failed to resolve import "@tanstack/react-table"
from "node_modules/@unicitylabs/sphere-ui/dist/index.js".

Note that the missing peer is the manifest half of the bug; the resolve error above is the other half — even a fully correct manifest would still force a notification-bell consumer to install a data table and a drag-and-drop stack just to import a bell.

The fixes

1. Declare the missing peer. "@dnd-kit/utilities": "^3.2.2" added to peerDependencies next to its siblings. Not an invented range — it is exactly what sphere, sphere-backoffice and sphere-dev-portal already carry.

2. Give the announcements module its own entry point. The announcement surface (src/components/announcements/) imports only react, lucide-react, react-markdown and remark-gfm — the latter two are regular dependencies, so they come along automatically. There is no reason a notification bell should drag in a data table.

This follows the subpath-export pattern the library already uses for ./forms, ./canvas, ./panels, ./hooks and ./analytics, rather than inventing a new one:

  • a new 'announcements/index' entry in tsup.config.ts,
  • a matching "./announcements" block in package.json's exports, in the same shape as its neighbours.

The main barrel is unchanged. src/index.ts still re-exports the announcement components, so the three apps that already import them from the root keep working. This adds a narrower door; it does not close the wide one.

Evidence

A green build in this repo proves nothing about what a consumer receives, so the fix was verified against the real consumer using a packed tarball.

Emitted subpath bundle is genuinely independent. The only bare specifiers in dist/announcements/index.js:

react, react/jsx-runtime, lucide-react, react-markdown, remark-gfm

No @tanstack/*, no @dnd-kit/*. dist/announcements/index.d.ts narrows further to react and lucide-react.

Consumer build, end to end. npm pack of this branch, installed into sphere-quest-frontend with npm install <tgz> --no-save (its manifest left untouched), imports repointed at @unicitylabs/sphere-ui/announcements:

step before after
npm run build (tsc && vite build) fails — cannot resolve @tanstack/react-table passes, 2499 modules, built in 1.27s
npm run test:run 105 passed (13 files)

Critically, that build passed with no @tanstack/react-table and no @dnd-kit/* anywhere in the app's node_modules (node_modules/@dnd-kit does not exist; node_modules/@tanstack contains only query-core and react-query). tsc passing also confirms the types condition of the new export resolves.

The import lines that worked, to be applied in that app after publication:

// src/App.tsx
import { AnnouncementModal, useAnnouncements, type ClientAnnouncement } from '@unicitylabs/sphere-ui/announcements';

// src/components/layout/Header.tsx
import { AnnouncementBell, type ClientAnnouncement } from '@unicitylabs/sphere-ui/announcements';

// src/services/announcementsClient.ts
import type { AnnouncementsClient, AnnouncementFeed, ClientAnnouncement } from '@unicitylabs/sphere-ui/announcements';

All experimental changes in sphere-quest-frontend were reverted afterwards; nothing was committed there.

Local checks

  • npm run test:run — 168 passed (23 files)
  • npm run typecheck — clean
  • npm run build — clean, emits dist/announcements/index.js (22.56 KB) + .d.ts
  • npm run lint is broken repo-wide (eslint not installed, no config) — pre-existing, untouched by this PR.

version is deliberately left at 0.1.38; the release workflow owns versioning.

KruGoL added 2 commits August 5, 2026 01:06
…subpath

dist/index.js statically imports @tanstack/react-table, @dnd-kit/core,
@dnd-kit/sortable and @dnd-kit/utilities. The last one was declared
nowhere in the manifest -- neither dependencies nor peerDependencies --
so the package imported a specifier it never asked consumers to provide.
It only ever resolved because every consumer so far happened to depend on
it directly.

Two fixes:

1. Add "@dnd-kit/utilities": "^3.2.2" to peerDependencies, next to its
   siblings. The range is the one sphere, sphere-backoffice and
   sphere-dev-portal already carry.

2. Give the announcement centre its own entry point, following the
   existing ./forms, ./canvas, ./panels, ./hooks and ./analytics pattern:
   a new tsup entry plus the matching "./announcements" exports block.
   The announcement surface only needs react, lucide-react, react-markdown
   and remark-gfm, so an app that wants a notification bell no longer has
   to install a data table and a drag-and-drop stack.

The main barrel still re-exports the announcement components unchanged,
so existing root imports keep working. This adds a narrower door without
closing the wide one.
…brary builds against

The peer was pinned to ^3.2.2, the version the three consuming apps happen to
carry today. The library itself builds and tests against ^3.0.0 (its own
devDependency), and every other peer here states the minimum supported major
rather than whatever a consumer currently has installed — @dnd-kit/core is
^6.0.0 while the apps carry ^6.3.1. Stating a floor higher than the real one
makes installs fail for consumers the library actually supports.
@KruGoL
KruGoL merged commit 7f77cb0 into main Aug 4, 2026
2 checks passed
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.

1 participant