Система проверки
«Проверка» в lh-ui — не пустая формальность: каждый пункт пресекает класс регрессий, которые реально случались в прошлом. В этом документе по пунктам описано, что проверяется и как читать вывод при неудаче.
verify:dts —— согласованность типов артефактов
Заголовок раздела «verify:dts —— согласованность типов артефактов»pnpm verify:dtsЧто проверяется: скомпилированные .d.ts в es/ / lib/ согласованы с объявлениями типов в исходниках, а файлы, на которые указывают ключи exports, реально существуют.
Типичные неудачи:
- Типы в исходниках изменены, но
pnpm buildне запущен повторно (артефакты устаревшие) sync:exportsсгенерировал ключ exports, но соответствующий файл не был собран (ошибка в пути)import typeнаписан какimport, и в артефакты попал лишний runtime-код
Исправление: полностью перезапустите pnpm build, затем pnpm verify:dts.
verify:styles —— шесть пунктов
Заголовок раздела «verify:styles —— шесть пунктов»pnpm verify:stylesСкрипт: scripts/verify-styles.mjs. Шесть проверок выполняются по порядку; неудача любой из них прерывает выполнение.
1. Палитра EP
Заголовок раздела «1. Палитра EP»Проверка по чёрному списку: девять значений цветов, оставшихся от EP (Element Plus) (#409eff, #e6a23c, #f56c6c, #67c23a, #909399, #606266, #303133, #ebeef5, #c0c4cc), не должны встречаться в scss-файлах директории styles/. Это защитный барьер регрессий после очистки D2, предотвращающий возвращение цветов старой системы — все цвета lh-ui берутся из определений токенов в styles/theme/common/variables.scss.
2. var fallback
Заголовок раздела «2. var fallback»Проверка, что каждая запись var(--lh-*) в компонентных scss содержит fallback-значение:
// ✅ Проходитcolor: var(--lh-text-primary, rgba(0, 0, 0, 0.88));
// ❌ Не проходитcolor: var(--lh-text-primary);Почему: когда токен отсутствует (пользователь подключил только часть стилей, в старой версии токена нет), var() без fallback разрешается в недействительное значение, и свойство отбрасывается — текст становится чёрным по умолчанию, границы исчезают. Наличие fallback гарантирует «работоспособную деградацию».
3. Токены через @use
Заголовок раздела «3. Токены через @use»Проверка, что компонентные scss ссылаются на слой токенов через @use, а не содержат разбросанные hex-литералы:
// ✅ Проходит@use 'theme/common/var' as *;.lh-card { background: var(--lh-bg-color, #fff); }
// ❌ Не проходит.lh-card { background: #ffffff; }Исключение: fallback-значение в var() может быть hex (это значения для деградации). В сообщении о неудаче указываются файл и номер строки.
4. Согласованность агрегации
Заголовок раздела «4. Согласованность агрегации»Проверка, что styles/index.scss (полная агрегация) согласован со «списком компонентов, полученным сканированием styles/*/index.scss». styles/index.scss генерируется scripts/build-styles.mjs, не правьте его руками — после добавления каталога компонента без повторной генерации возникнет рассогласование.
5. Единый источник классов переходов
Заголовок раздела «5. Единый источник классов переходов»Проверка, что в компонентных scss отсутствуют буквальные записи -enter-from / -leave-from, написанные вручную:
// ❌ Не проходит: классы переходов написаны вручную в двойном виде.lh-dialog-fade-enter-from { opacity: 0; }
// ✅ Проходит: используется mixin@include lh-enter-both('.lh-dialog-fade') { opacity: 0; }Почему: во Vue2 используются -enter, в Vue3/React — -enter-from; при ручном написании один конец обязательно будет упущен (см. transition-mixins). Раньше 16 компонентов имели раздвоенные классы, и правка в одном месте приводила к пропуску в другом.
6. Тёмная доступность
Заголовок раздела «6. Тёмная доступность»Проверка, что токены в var.scss, значение которых имеет вид #{$lh-foo} (запечённые на этапе компиляции в светлый цвет), имеют соответствующее переопределение в var-dark.scss.
Это самый важный пункт. Подобные пробелы однажды привели к тому, что в тёмной теме текст меню / таблиц / таймлайна использовал светлые значения и был невидим (чёрный текст на чёрном фоне). См. Ловушка запекания на этапе компиляции.
Примечание: ранее был исправлен один ложноположительный результат — verify:styles из-за смещения индекса ложно сообщал о нарушение в строках, освобождённых от проверки no-fallback (коммит 791ff32). Если сообщение об ошибке выглядит необоснованным (ошибка в строке, которая должна быть освобождена), сначала убедитесь, что это не та известная проблема.
verify:theme —— гейт контрастности AA
Заголовок раздела «verify:theme —— гейт контрастности AA»pnpm build # ← нужно запустить первым, читает артефакты es/pnpm verify:themeСкрипт: scripts/verify-theme-contrast.mjs.
Что проверяется: во всех пяти встроенных темах (и их тёмных вариантах) контрастность WCAG для всех пар «текст / фон» составляет не менее 4.5:1 (уровень AA).
Почему нужно читать артефакты es/: vars пресетов тем принимают окончательную форму только после сборки (результат вывода buildPresetDarkVars тоже находится в артефактах).
Типичные неудачи:
- В новом пресете со светлым основным цветом не задан
--lh-color-on-primary(белый текст на светлом основном цвете даёт всего 3.x:1) - Цвет текста выделенного пункта (
--lh-selected-color) имеет недостаточную контрастность с цветом фона при наведении
Исправление: сделайте соответствующие цвета темнее / светлее, пока контрастность не достигнет нормы. getContrastRatio() и getRelativeLuminance() (экспортируются из src/theme/themes/index.ts) можно посчитать локально, не запуская каждый раз полный гейт.
CI эту проверку не запускает — она требует предварительного build и потребляет немало ресурсов. Перед локальным релизом её выполняют вручную.
verify:versions —— согласованность версий
Заголовок раздела «verify:versions —— согласованность версий»pnpm verify:versionsСкрипт: scripts/check-version-sync.mjs.
Что проверяется: диапазон зависимости @lh-ui/share в package.json библиотек lh-ui-plus и lh-ui-vue2 покрывает текущую версию share.
Текущее состояние: проходит, когда share имеет версию 0.3.0. После выпуска 0.4.0 проверка завершится неудачей — потому что диапазоны зависимости в обеих UI-библиотеках всё ещё ^0.3.0. Это ожидаемое поведение: согласно красной линии 5 (сначала релизится share, затем UI-библиотеки), после релиза нужно пойти в каждый из двух родственных репозиториев, выполнить pnpm up @lh-ui/share@0.4.0 и провести регрессию.
lint и typecheck
Заголовок раздела «lint и typecheck»| Команда | Область сканирования |
|---|---|
pnpm lint |
src / tests / scripts / vite.config.ts / vitest.config.ts |
pnpm typecheck |
src/**/* (поле include в tsconfig.json) |
docs/ не входит в область сканирования — сайт документации является независимым Astro-проектом, и его качество контролируется pnpm docs:build. Аналогично styles/ не входит в область typecheck (SCSS управляется verify:styles).
Гейт зависимости от фреймворка в lint: CI проверяет (grep) наличие в src/ строк import 'vue' / import 'react' / @dcloudio/* — это красная линия 1: core должен быть независим от фреймворков.
pnpm testtests/unit/ — единственная копия unit-тестов для core (красная линия 3): результатом пользуются три библиотеки, UI-библиотеки не должны его копировать. Тесты чистых функций не требуют рендеринга компонентов — создаются литералы rect, проверяется вывод, все четыре конца используют один и тот же набор утверждений.
Ключевые файлы тестов:
| Файл | Покрытие |
|---|---|
theme.spec.ts |
Согласованность пресетов (синхронизация двух источников: JS vars и SCSS-переменных) |
core/*.spec.ts |
Логика компонентов core |
shared/*.spec.ts |
Алгоритмы общего ядра (popper / keyboard / virtual и др.) |
Полный цикл проверок
Заголовок раздела «Полный цикл проверок»Полный чек-лист перед релизом:
pnpm installpnpm lintpnpm typecheckpnpm testpnpm build # Обратите внимание: sync:exports изменит package.jsonpnpm verify:dtspnpm verify:styles # Шесть пунктовpnpm verify:theme # Требует предварительного buildpnpm verify:versions # После релиза переходит в downstream-обработкуpnpm docs:build # Сайт документацииВ prepublishOnly (запускается командой pnpm release) входят только build + verify:dts + verify:styles. Поэтому test / lint / typecheck / verify:theme нужно запускать явно и вручную.
Связанные документы
Заголовок раздела «Связанные документы»Copyright © 2024-2026 FengMo WenXue