Установка
Что ставится, почему именно это и куда — dependencies или devDependencies. Плюс иконки и опциональные интеграции.
Быстрый старт даёт один рабочий путь без объяснений. Эта страница объясняет: почему состав зависимостей именно такой, что из него попадает в бандл, а что живёт только на сборке.
Требования
| Что | Версия | Почему жёстко |
|---|---|---|
| Node | ≥ 22 | Объявлено в engines, пакет ESM-only |
"type": "module" | обязательно | CommonJS-сборки нет и не планируется |
| Vue | ^3.5 | peer-зависимость |
@floating-ui/dom | ^1.8 | обязательная runtime peer-зависимость |
| UnoCSS | ≥ 66 | вместе с @unocss/preset-mini или @unocss/preset-wind4 |
@feugene/fint-i18n — peer тоже, но помеченный необязательным: без него
компоненты говорят по-английски встроенными строками, а не падают. Подробности —
на странице локализации.
Единственный поддерживаемый способ
Подключение идёт через UnoCSS-пресет presetGranularNode и granular-провайдер
пакета. Прямые импорты CSS-файлов, импорт «всего сразу» из корня и подключение
styles.css в обход пресета не поддерживаются — они работают ровно до первого
обновления и ломаются молча.
Исключение одно и названо в самом пакете: @feugene/granularity/styles.css —
готовый лист с токенами, базовым слоем, preflight и обеими темами для тех, кто
пресет не запускает вовсе. Он даёт рабочую основу, но не даёт утилитарных
классов, которыми нарисованы шаблоны компонентов.
Что и куда
# в dependencies — попадает в приложение
yarn add vue @feugene/granularity @floating-ui/dom @unocss/reset
# в devDependencies — исполняется только на сборке
yarn add -D unocss @feugene/unocss-preset-granular @unocss/preset-mini@feugene/granularity — в dependencies: его компоненты импортируются из
исходников приложения и попадают в бандл.
@floating-ui/dom — в dependencies приложения, а не внутрь пакета. На нём
построено позиционирование GrDropdown, GrSelect, GrAutocomplete,
GrTreeSelect, GrTooltip и GrPopover. Пакет держит библиотеку внешней и не
бандлит внутрь dist — иначе приложение, которое само использует floating-ui,
получило бы вторую копию.
Пресет, unocss и preset-mini — в devDependencies: они исполняются в
uno.config.ts и ни одной строкой не попадают в бандл. granularityProvider
реэкспортируется самим пакетом и своих зависимостей не требует.
Модальный слой — GrModal, GrDialog, GrDrawer, GrImageViewer,
GrCommandPalette — не требует внешних зависимостей вовсе. Ловушка фокуса,
inert для фона, порядок Esc и возврат фокуса — собственные примитивы пакета.
@headlessui/vue был убран в 0.15.0 и peer-зависимостью не является: если он
остался в проекте ради этого пакета, его можно снести.
Наращивание конфига
Минимальный рабочий конфиг — провайдер и больше ничего:
import { defineConfig, presetMini } from 'unocss'
import { presetGranularNode } from '@feugene/unocss-preset-granular/node'
import granularityProvider from '@feugene/granularity/granular-provider/node'
export default defineConfig({
presets: [presetMini(), presetGranularNode({ providers: [granularityProvider] })],
})Он уже подмешивает tokens.css и base.css, включает все компоненты
провайдера с их preflight и поднимает rules, variants и safelist. Дальше
опциями сужают и уточняют:
| Опция | Что делает |
|---|---|
components | Список компонентов вместо «всех». Единственное место, где вы платите за гранулярность вниманием |
themes.names | Какие темы попадут в лист. По умолчанию — все темы провайдера |
themeFiles, tokensFile, baseFile | Подмена CSS темы, токенов или базового слоя файлами приложения |
layer | Кладёт preflight пакета в отдельный слой и даёт ему свой виртуальный модуль |
granularContent(options) в content верхнего уровня — обязателен, когда
компоненты приезжают подпутями из собранного dist: extractor UnoCSS иначе
туда не заглянет. Читается он только из верхнего уровня конфига, не из пресета.
Иконки
Свои иконки пакет привозит с собой. Стрелка селекта, крестик очистки,
галочка выбранной опции, спиннер, ручка переноса компилируются в dist при
сборке пакета. Ставить unplugin-icons или коллекцию ради них не нужно.
Своя иконка приходит двумя способами. Пропы icon принимают либо Vue-компонент,
либо класс:
<script setup lang="ts">
import IconUser from '~icons/lucide/user'
</script>
<template>
<!-- Компонент: работает всегда, настраивать нечего. -->
<GrTabs :tabs="[{ value: 'a', label: 'Profile', icon: IconUser }]" />
<!-- Класс: CSS для него генерирует ваш конфиг, а не пакет. -->
<GrTabs :tabs="[{ value: 'a', label: 'Profile', icon: 'i-lucide-user' }]" />
</template>i-lucide-* — утилита UnoCSS, и делает её ваша сборка. Без presetIcons и
коллекции иконок класс останется классом: место под иконку будет, картинки не
будет, и сборка при этом пройдёт молча.
yarn add -D @unocss/preset-icons @iconify-json/lucideОпциональные интеграции
@feugene/unplugin-granularity— резолвер дляunplugin-vue-components: авто-импорт компонентов и директив в шаблонах. Вставляет статические импорты в SFC, поэтому tree-shaking остаётся идеальным.createGranularityиз@feugene/granularity/vue— runtime-адаптер для директив вrender/JSX, общегоprovideиglobalProperties. Сам он не импортирует ни одного компонента: что передадите, то и зарегистрируется.
Оба дополняют основной способ установки, а не заменяют его. Настройка обоих — в конфигурации.