Версионирование

  • Обновления и помощь
  • 6 мин
  • кода: 1

Что обещает 1.x, как пакеты семейства связаны версиями и чего библиотека пока не обещает.

Ревизия 2026-10-16

На этой странице

Вопрос внедренца звучит не «какая сейчас версия», а «сколько эта версия проживёт». Честный ответ на сегодня: окно поддержки не объявлено. Ниже — что вместо него есть, что из этого проверяемо и что делать, пока обещания нет.

С 1.0

Библиотека нумерует выпуски по Semantic Versioning, и с 1.0 публичная поверхность — компоненты, их подпути, токены и реестры — ломается только мажором. На 0.x было иначе: минорный выпуск мог сломать совместимость, и ломал. Версия 0.41.0 вынесла GrCodeBlock из ядра в @feugene/granularity-code, и подпуть @feugene/granularity/components/GrCodeBlock исчез:

diff
- import { GrCodeBlock } from '@feugene/granularity'
+ import { GrCodeBlock } from '@feugene/granularity-code/components/GrCodeBlock'

Причина названа в журнале изменений и она про 1.0: вынести что-то из замороженного ядра стоит мажора, поэтому переезды такого рода делались до заморозки, а не после.

На мажоре 1 ^ и ~ различаются. ^1.0.0 разворачивается в >=1.0.0 <2.0.0 и принимает новые миноры, ~1.0.0 — в >=1.0.0 <1.1.0. На нулевом мажоре — у @feugene/granularity-datasource 0.1.x и у peer @feugene/fint-i18n — ^ по-прежнему значит то же, что ~.

Каждый пакет версионируется сам

Общей версии у семейства нет, и это не недосмотр. У ядра и спутников разный цикл: ядро выпускает патч за патчем, спутник может неделями стоять на своей версии, а @feugene/granularity-datasource и вовсе ещё на 0.x. Лишний выпуск спутника ради выпуска ядра означал бы обновление, за которым не стоит ни одного изменения.

Из этого следует три вещи, и все три видны в репозитории:

  1. У каждого пакета свой журнал изменений. Общего журнала в корне нет намеренно — журналы на портале собраны из них.
  2. У каждого пакета свой тег. Ядро выпускается тегом vX.Y.Z, спутник — <имя-каталога>-vX.Y.Z, например granularity-charts-v1.0.4.
  3. Публикация идёт из тега. Пуш тега запускает публикацию в npm с --provenance: у пакета в npm есть прослеживаемое происхождение, и это проверяет ваш сканер, а не мы. Зеркало в GitHub Packages выходит под scope @efureev и без provenance.

Матрица совместимости

Спутник объявляет, с какой версией ядра и конвейера он работает, — не словами, а диапазоном в peerDependencies. Ваш менеджер пакетов прочитает его сам и о несовместимой паре скажет: npm — предупреждением, pnpm и yarn berry со строгими настройками — отказом установки. Здесь тот же диапазон в читаемом виде:

ПакетЯдро @feugene/granularityКонвейер @feugene/granumVue
@feugene/granularity-charts>=1.0.0 <2.0.0>=2.0.0 <3.0.0^3.5.0
@feugene/granularity-chrono>=1.0.0 <2.0.0>=2.0.0 <3.0.0^3.5.0
@feugene/granularity-code>=1.0.0 <2.0.0>=2.0.0 <3.0.0^3.5.0
@feugene/granularity-dashboard>=1.0.0 <2.0.0>=2.0.0 <3.0.0^3.5.0
@feugene/granularity-datasource——^3.5.0
@feugene/granularity-devtools>=1.0.0 <2.0.0—^3.5.0
@feugene/granularity-editor>=1.0.0 <2.0.0>=2.0.0 <3.0.0^3.5.0
@feugene/granularity-forms-schema>=1.0.0 <2.0.0>=2.0.0 <3.0.0^3.5.0
@feugene/granularity-media>=1.0.0 <2.0.0>=2.0.0 <3.0.0^3.5.0
@feugene/granularity-test-kit—>=2.0.0 <3.0.0^3.5.0
@feugene/unplugin-granularity>=1.0.0 <2.0.0——

В таблице — связь с ядром, конвейером и Vue. Остальные peer-зависимости — например, опциональные @feugene/fint-i18n >=0.9.0 <1.0.0 и @feugene/unplugin-granularity, @feugene/granularity-chrono у forms-schema, библиотеки редакторов и схем у своих спутников — смотрите в package.json пакета. У test-kit конвейер и Vue опциональны.

Прочерк означает, что пакет этой зависимости не объявляет вовсе: granularity-datasource не знает ни о ядре, ни о конвейере — он про данные, а не про разметку; test-kit работает с любым ядром, потому что проверяет CSS и DOM, а не импортирует компоненты; unplugin-granularity разрешает компоненты, не порождая ни одного правила.

Семейство пришло к 1.0 вместе, и диапазоны об этом и говорят: нижняя граница >=1.0.0, верхняя — <2.0.0. Раньше граница была <1.0.0 и означала «дальше границы обещаний нет». 1.0 контракт переопределила, и диапазоны переписаны вместе с ним — ровно как и было обещано.

Колонка конвейера живёт своим мажором: с выпуска 1.1.0 спутники собраны granum 2 и объявляют >=2.0.0 <3.0.0 — granum 1 рецепты темизации и запрет корневого импорта, на которые опирается документация, не выполняет.

Таблица набрана руками, но сверяется с манифестами в CI портала: диапазон ядра или Vue, разошедшийся с package.json спутника, роняет прогон. Колонку конвейера гейт пока не сверяет. И сверка идёт с тем тегом, на который закреплён подмодуль библиотеки, а не с тем, что лежит в npm сию секунду. Источник истины — peerDependencies установленного пакета.

Требования к окружению

ЧтоВерсияОткуда
Node>=22engines во всех пакетах семейства
Vue^3.5.0peer-зависимость
Формат модулейтолько ESM"type": "module", CommonJS-сборки нет

Эти три строки — тоже часть совместимости, и меняются они по тем же правилам: поднять нижнюю границу Node — ломающее изменение, и с 1.0 оно приезжает только мажором.

Документация одной версии

Документация описывает одну версию — ту, на которую закреплён портал; сейчас это линия 1.x. Архива /v0/ и переключателя версий нет: страницы 0.x на портале не сохранены, а переезд с них описан в миграции.

Версия в шапке читается из манифеста установленного ядра при сборке и руками не пишется.

Чего библиотека пока не обещает

Раздел существует потому, что молчание здесь читается как обещание. Ни одного из перечисленного сегодня нет:

  • срок жизни версии. Сколько линия 1.x будет получать исправления после выхода 2.0 и сколько живёт минор после следующего — не объявлено;
  • период депрекации. Подпуть может исчезнуть в том же выпуске, в котором появилась замена: так и вышло с GrCodeBlock;
  • бэкпорт исправлений безопасности в предыдущие миноры;
  • метаданные since и deprecated у компонентов. Страница компонента не говорит, в какой версии появился проп: этих данных в библиотеке пока нет, и портал не станет их выдумывать.

Что делать вместо этого:

  1. Закрепляйте минор, если нужна предсказуемость: ~1.0.0 вместо ^1.0.0 — см. выноску выше, — и проверьте, что в package.json стоит диапазон, а не latest.
  2. Читайте журнал пакета, который поднимаете. Не общий: у каждого свой, и ломающее изменение описано там с диффом.
  3. Поднимайте по одному. Спутник и ядро связаны диапазоном, а не общей версией: обновление ядра не требует обновления спутников, пока диапазон сходится.

Где смотреть изменения

Журналы изменений на портале собраны из журналов пакетов в репозитории библиотеки — по одному на пакет, с диффами и объяснениями. Это тот же текст, что в репозитории: портал его не пересказывает.