Миграция

  • Обновления и помощь
  • 7 мин

Переезды между мажорами: что сломали переходы на 1.0, 2.0 и 3.0 и как их пройти.

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

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

Мажорных переходов у библиотеки три. С 2.x на 3.0 значения компонентов переехали в темы: имена токенов — контракт ядра, значения даёт тема. С 1.x на 2.0 пришли темы и режимы: тема стала данными пакета токенов, светлый и тёмный — её режимами, сборка — granum 3. С 0.x на 1.0 сменился конвейер, которым приложение собирает CSS. Все три переезда ломающие, хотя ни один импорт компонента в них не меняется.

С 2.x на 3.0

Компоненты, их пропсы и внешний вид «Сланца» не меняются: значения, которые видят компоненты в каждом режиме и острове, совпадают с 2.x. Меняется то, где эти значения живут и кто отвечает за их полноту.

Было в 2.xСтало в 3.0
peer @feugene/granum >=3.8.0 <4.0.0>=3.10.0 <4.0.0; пакет токенов @feugene/granularity-tokens — мажор 2
конфиг granum без themes собирал тему каталога по умолчаниюthemes обязателен: основную тему выбирает приложение, без него — ошибка granum со списком тем каталога
GR_DEFAULT_THEME_IDGR_BASE_THEME_ID — базовая тема пакета, а не основная тема чьей-то сборки
значения токенов компонентов — у самих компонентовзначения — в теме, разделом components/@feugene/granularity/<GrX>/
токен темы компонент читал с запасным значениембез запасного: нехватку называет granum doctor (theme-incomplete)
--gr-button-neutral-bg — хук, его задавала тематокен темы; хук — ручка приложения, и в данных темы он — находка theme-token-foreign
theme.json с режимами массивом и componentDefaults в корнережимы — объектом, пропсы по умолчанию — в extensions.granularity.componentDefaults, файл режима — плоские значения

Свои значения поверх темы приложение задаёт как прежде — modes.tokenOverrides записи темы или своим CSS; хук остаётся ручкой приложения поверх токена темы.

Молча ломается одно — своя тема без extends, которая опиралась на запасные значения компонентов. Ошибки сборки нет: компонент просто не получает токен, а granum doctor называет его поимённо. Значения дописываются в раздел components темы, либо тема наследует тему каталога; начать с копии удобно командой gr-theme-copy slate <id>. Тема с extends: 'slate' работает как прежде и теперь получает от «Сланца» и значения компонентов.

Спутники charts и media перешли на ядро 3 мажорами 3.0: их значения тоже живут в теме, и диапазон ядра у них — >=3.1.0 <4.0.0. chrono, code, dashboard, editor и forms-schema своих значений у темы не держат и работают с обоими мажорами ядра. Полная карта переезда — в документации библиотеки.

С 1.x на 2.0

Компоненты, их пропсы и внешний вид «Сланца» не меняются: значения токенов совпадают с 1.x, кроме двух исправленных дефектов тёмного острова — они описаны в журнале изменений. Меняется то, как тема попадает в сборку и как переключается режим.

Было в 1.xСтало в 2.0
peer @feugene/granum мажора 1 или 2>=3.0.0 <4.0.0, у выпусков с темами сборки — >=3.8.0 <4.0.0; движок @feugene/granum-engine-wind — тоже мажор 3
themes: { names: ['light', 'dark'] }themes: [{ theme: 'slate', modes: ['light', 'dark'] }] — список тем сборки; объект themes падает InvalidConfigError
themes.define, themes.tokenOverridesmodes.define, modes.tokenOverrides в записи темы
data-theme="dark" на корнепара data-theme="slate-dark"; классов .light и .dark нет
[data-theme='dark'] .x в своём CSS[data-theme$='-dark'] .x или пара целиком; dark: в утилитах работает без правок
useTheme().theme — имя режимаtheme — текущая тема сборки; режим — mode
setTheme('dark'), toggleTheme()setMode('dark'), toggleMode(); setTheme(id) переключает тему сборки
тип ThemeNameGrModeName, GrThemeId
<GrConfigProvider theme="dark"><GrConfigProvider mode="dark">; theme — остров другой темы сборки
@feugene/granularity/theme: extendTheme, createTheme@feugene/granularity-tokens/theme: extendMode, createMode, defineTheme
@feugene/granularity/theme/apply@feugene/granularity-tokens/theme/apply
grThemeTokens из @feugene/granularity/tokensgrRoleTokens из @feugene/granularity-tokens
styles/tokens.css, styles/themes/light.css и dark.cssthemes/slate.css — оба режима одной темы

Манифест режимов отдают один раз, там, где создаётся состояние: initThemeEarly({ manifest }) или app.use(granularityThemePlugin, { manifest }) с manifest из virtual:granum/themes. Ключ хранилища прежний — gr-theme, и у основной темы в нём по-прежнему имя режима: выбор пользователя переживает обновление. Пакет токенов отдельно ставить не нужно — он приезжает зависимостью ядра.

Молча ломается одно — атрибут и селекторы с именем режима вместо пары. data-theme="dark", поставленный руками, и свой CSS под [data-theme='dark'] не дают ни ошибки, ни предупреждения: компоненты просто остаются в режиме по умолчанию. theme="dark" у GrConfigProvider dev-сборка хотя бы подсветит предупреждением.

Первые выпуски 2.x писали тему и режимы отдельными ключами — theme: 'slate' и modes: { names: [...] }. С granum 3.8 это запись списка themes, а previews и css.previews стали дополнительными темами со своими листами. Старые ключи granum отвергает ошибкой конфига с подсказкой, куда переехало значение.

Спутники перешли на ядро 2 своими мажорами 2.x в тот же день: смешивать ядро 2 со спутником, собранным под ядро 1, нельзя — манифесты granum 2 и 3 несовместимы. Полная карта переезда — в документации библиотеки, ключи конфига granum — в его руководстве (ru, en).

С 0.x на 1.0

Было в 0.xСтало в 1.0
peer @feugene/unocss-preset-granularpeer @feugene/granum >=1.0.0 <2.0.0 и движок @feugene/granum-engine-wind
uno.config.tsgranum.config.ts; движок передаётся инстансом — engine: windEngine()
CSS склеивался по порядку подключенияCSS приезжает модулем virtual:granum.css пятью слоями granum.*
сброс браузерных стилей — обычным CSSсброс — в слое: @import '…' layer(reset);, иначе он перебьёт библиотеку
defineGranularComponent, defineGranularProviderdefineGranumComponent, defineGranumProvider из @feugene/granum/contract — для авторов провайдеров

Спутники, которые зависят от ядра, перешли на 1.0 в тот же день: их диапазон ядра теперь >=1.0.0 <2.0.0, и с ядром 0.x он не сходится. Поэтому ядро и спутники обновляются вместе. Пошаговое руководство — в документации granum (ru, en). Ломающие правки внутри линии 0.x — в журнале изменений.

Что появится здесь к следующему мажору

  1. Карта изменений API — что переименовано, что удалено, что поменяло значение по умолчанию. Таблицей, а не прозой: по прозе не сделать поиск по имени пропа.
  2. Codemod. Переименования выполняются скриптом, а не руками: он живёт в репозитории рядом с миграцией и запускается одной командой.
  3. Что ломается молча. Отдельный раздел под изменения, которые не дают ни ошибки сборки, ни предупреждения, — сдвиг значения по умолчанию, смена порядка разрешения, другой ARIA-контракт. Это самая дорогая часть переезда и самая короткая в чужих гайдах. Один такой случай известен уже по 1.0 — сброс вне слоя, см. типовые поломки.
  4. Порядок действий для приложения, которое обновляется не сразу: что можно ставить рядом, что конфликтует, где проходит граница совместимости.
  5. Оценка трудоёмкости по размеру приложения — чтобы решение «переезжать сейчас или в следующем квартале» принималось по числу, а не по настроению.

Версии документации

Документация одна и описывает линию 3.x; архива 0.x, 1.x и 2.x на портале нет. Версия в шапке читается из манифеста установленного ядра на сборке и руками не пишется — она совпадает с тем, на чём собран портал.

Подробности политики версий — на странице версионирования.

Переход с другой библиотеки — это не миграция в этом смысле. Карты соответствия компонентов для него готовятся на отдельной странице — «Переход с другой библиотеки».