Пакет в серверных компонентах
Компоненты кита импортируются прямо в серверный компонент Next.js App
Router — оборачивать их своим файлом с "use client" не нужно: директива стоит
в самом пакете, по файлам.
Но в конфигурации потребителя обязательна ещё одна строка:
// next.config.mjs
export default { experimental: { optimizePackageImports: ["@olddevs/ui"] } };Она обязательна ровно в том же смысле, что и @source для Tailwind: без неё
сборка проходит успешно, а результат негодный. Замер на приложении Next.js 15.5
(First Load JS, пакет поставлен тарболом):
| Что импортирует страница | Без строки | Со строкой |
|---|---|---|
| ничего из кита (базовая линия) | 102 кБ | 103 кБ |
AddIcon из @olddevs/ui/icons | 103 кБ | 103 кБ |
одна Button из корня | 408 кБ | 114 кБ |
cn и tableStateToParams | 408 кБ | 103 кБ |
Третья строка читается так: импорт одной кнопки приносил пользователю весь кит целиком. Четвёртая — что серверный компонент, которому нужны две чистые функции и ни одного компонента, отгружал те же 306 кБ клиентского кода.
Причина не в упаковке пакета, а в границе клиентского графа: корневой
entrypoint реэкспортирует сотню клиентских модулей, и деревотряска через эту
границу не работает. optimizePackageImports переписывает импорт из
entrypoint в набор точечных, и цена возвращается к разумной. Разбор —
ADR-0029.
Подпуть редактора — своей строкой. Вход @olddevs/ui/editor — такой же
barrel: рядом с серверным RichTextView он реэкспортирует клиентский
RichTextEditor. Корневая строка подпуть не покрывает, и страница, которой
нужен один просмотр документа, отгружает весь редактор вместе с движком:
// next.config.mjs — если импортируете @olddevs/ui/editor
export default {
experimental: { optimizePackageImports: ["@olddevs/ui", "@olddevs/ui/editor"] },
};Замер фикстуры потребителя (RichTextView с блоком кода в серверном
компоненте): 435 кБ First Load JS без второй строки и 137 кБ с ней — в
клиент едет только остров кнопки «Копировать». Входы @olddevs/ui/editor/schema
и @olddevs/ui/editor/highlight — не barrel и клиентских модулей не содержат,
строка им не нужна.
Утилиты (cn, tableStateToParams, formatMask и остальные из
api/utilities.md) серверно-безопасны: React они не
импортируют и в клиентский граф не тянут. Отдельного входа вроде
@olddevs/ui/server у пакета нет и не планируется — со строкой выше он не
нужен.