@feugene/unplugin-granularity
| Install | |
|---|---|
npm install @feugene/unplugin-granularity |
|
| Latest Version: | 1.2.1 |
| Vue: | 3 |
| License: | LicenseRef-Granularity-EUC-1.1 |
| Last Updated: | Oct 22, 2026 |
| Links: | GitHub · npm |
@feugene/unplugin-granularity
unplugin-vue-components
резолвер для дизайн-системы @feugene/granularity — один на
ядро и все пакеты-спутники.
Резолвит компоненты Gr* и директивы v-* из шаблонов Vue на гранулярные sub-path-экспорты
пакетов (@feugene/granularity/components/<Name>, @feugene/granularity-chrono/components/<Name>,
@feugene/granularity/directives/<module>), а не на корневой index: в бандл попадает ровно то, что
встретилось в шаблонах, а granum видит компонент по подпути — импорт из корня он отвергает.
Список компонентов вести не нужно: резолвер находит пакеты экосистемы в package.json приложения и
читает их exports.
Установка
# yarn
yarn add -D @feugene/unplugin-granularity unplugin-vue-components
# npm
npm i -D @feugene/unplugin-granularity unplugin-vue-components
# pnpm
pnpm add -D @feugene/unplugin-granularity unplugin-vue-components
@feugene/granularity и unplugin-vue-components подключаются как
peer-зависимости — пакет сам ничего не тащит в рантайм и не дублирует типы.
Использование
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import Components from 'unplugin-vue-components/vite'
import { GranularityResolver } from '@feugene/unplugin-granularity'
export default defineConfig({
plugins: [
vue(),
Components({
resolvers: [GranularityResolver()],
}),
],
})
После этого в шаблонах не нужно ручных import-ов:
<template>
<GrInput v-model="value" v-hotkey.enter="submit" />
<GrButton @click="submit">Go</GrButton>
</template>
unplugin-vue-components сам вставит в <script setup> что-то вроде:
import { GrButton } from '@feugene/granularity/components/GrButton'
import { GrInput } from '@feugene/granularity/components/GrInput'
import { vHotkey } from '@feugene/granularity/directives/hotkey'
Никаких @feugene/granularity (корневой импорт) здесь нет — Rollup/Rolldown
видит только реально используемые модули.
Опции
GranularityResolver({
packages: ['@feugene/granularity', '@feugene/granularity-chrono'], // default — из package.json
root: process.cwd(), // откуда читать package.json и искать пакеты
prefix: 'Gr', // имена без префикса не резолвятся; default 'Gr'
importStyle: false, // подтягивать <pkg>/components/<Name>/styles.css; default false
directives: true, // авто-импорт директив (v-hotkey и т.п.); default true
exclude: /^GrIn/, // игнорировать имена по RegExp
})
| Опция | Тип | По умолчанию | Назначение |
|---|---|---|---|
packages |
string[] |
все @feugene/granularity* из package.json |
Чьи компоненты резолвить. Не нашлось ни одного — ядро. |
root |
string |
process.cwd() |
Корень приложения: его package.json и точка поиска пакетов. |
prefix |
string |
'Gr' |
Имена без префикса резолвер не смотрит. |
importStyle |
boolean | 'css' |
false |
Подгружать ли CSS компонента как side-effect. Пакетам экосистемы не нужно — см. «Нюансы». |
directives |
boolean |
true |
Включать ли второй резолвер — для директив. |
exclude |
RegExp | undefined |
— | Исключение из обработки (применяется и к компонентам, и к директивам). |
Как резолвер находит компоненты
- Пакеты — из
dependencies,devDependenciesиpeerDependenciesприложения: все@feugene/granularityи@feugene/granularity-*. Пакеты без компонентов (-test-kit,-devtools) ничего не добавляют. - Компоненты — ключи
./components/<Name>вexportsкаждого пакета. Индекс строится один раз, при первом теге из шаблона. - Части составных компонентов (
GrListItem,GrTabPanel) импортируются из подпути родителя —@feugene/granularity/components/GrList: туда ведёт их запись вexports. Такой импорт guard и селекция granum судят по владельцу с любой версии 2.x; подпуть самой части (components/GrListItem) granum сводит к владельцу только с 2.1 и только у пакета, собранного 2.1. - Неизвестное имя (опечатка, свой компонент приложения) не резолвится: импорта несуществующего пути не будет, Vue предупредит о неизвестном компоненте.
- Имя, которое экспортируют два пакета, резолвер не трогает: такой компонент импортируют руками.
Порядок резолверов не важен: имя ведёт ровно в тот пакет, который его экспортирует. Собственные
резолверы спутников (@feugene/granularity-chrono/resolver и другие) и фабрика
createGranularResolver остаются для уже написанных конфигов и работают рядом.
Поддерживаемые директивы
| Шаблон | Реэкспорт | Sub-path |
|---|---|---|
v-autofocus |
vAutofocus |
@feugene/granularity/directives/autofocus |
v-autosize |
vAutosize |
@feugene/granularity/directives/autosize |
v-click-outside |
vClickOutside |
@feugene/granularity/directives/clickOutside |
v-dropzone |
vDropzone |
@feugene/granularity/directives/dropzone |
v-hotkey |
vHotkey |
@feugene/granularity/directives/hotkey |
v-loading |
vLoading |
@feugene/granularity/directives/loading |
Директивы — фиксированным списком: имя экспорта и модуль из имени в шаблоне не
выводятся. При добавлении новой директивы в @feugene/granularity — добавьте её и в
src/manifest.ts этого пакета; гейт пакета сверяет список с
exports ядра.
Нюансы
- Стили ядра подключать через резолвер не нужно. Чанки компонентов CSS не
импортируют: собственный
styles.cssкомпонента granum берёт из манифеста пакета в слойgranum.components, а у большинства компонентов своего CSS нет вовсе: их оформление — утилиты, которые генерирует движок по выбранным компонентам. Отсюда иimportStyle: falseпо умолчанию: включённая опция ссылалась бы на@feugene/granularity/components/<Name>/styles.css, которого ядро не публикует, и ломала бы сборку. Опция осталась для провайдеров, которые раздают CSS отдельными файлами вexports. Статический запасной вариант без granum —@feugene/granularity/styles.css(токены, темы, base и preflight, без утилит). - Свои компоненты на
Gr…. Компонент приложения, которого нет вexportsпакетов, резолвер не тронет. Если имя совпало с компонентом пакета — исключите егоexclude(например/^GrLegacy/). GlobalComponentsдля Volar. Резолвер работает вместе сdtsопциейComponents({ dts: 'components.d.ts' })— тогда Volar/vue-tscподхватят типы компонентов в шаблонах автоматически.- Webpack/Rspack/Rollup. Резолвер не привязан к vite — его можно передавать
в
resolversлюбого адаптераunplugin-vue-components.
Лицензия
Apache License 2.0 с дополнительной оговоркой об этичном использовании — см. LICENSE. Оговорка добавляет ограничение по применению поверх Apache-2.0, поэтому лицензия source-available, а не одобренная OSI открытая.
Related Packages
varlet import resolver for unplugin-vue-components and unplugin-auto-import
Rich-text editing for @feugene/granularity: a TipTap-backed GrRichText field wit...
Vue DevTools panel for @feugene/granularity — where a prop value came from, the...
Version History
| Version | Released | License |
|---|---|---|
| 1.2.1 | LicenseRef-Granularity-EUC-1.1 | |
| 1.2.0 | LicenseRef-Granularity-EUC-1.1 | |
| 1.1.1 | LicenseRef-Granularity-EUC-1.1 | |
| 1.1.0 | LicenseRef-Granularity-EUC-1.1 | |
| 1.0.0 | LicenseRef-Granularity-EUC-1.1 | |
| 0.7.1 | Custom | |
| 0.7.0 | Custom | |
| 0.6.1 | Custom | |
| 0.6.0 | Custom | |
| 0.5.0 | Custom | |
| 0.4.0 | Custom | |
| 0.3.1 | Custom | |
| 0.3.0 | Custom | |
| 0.2.0 | Custom |