Перейти к содержимому

Обзор конвейера

Команда pnpm codegen выполняет codegen/src/index.ts; полный конвейер выглядит так:

Номер версии из package.json
│
▼
loadTokenFiles() Загрузка tokens/*.json, структурная валидация Ajv, уплощение flatten
│ Возвращает LoadedTokenFile[] (каждый файл содержит namespace / isDark / flat)
▼
resolveTokens() Разрешение ref (с обнаружением циклов) + слияние тёмной темы
│ Возвращает { tokenSet, orphanDarkPaths, refMap }
▼
loadSpecs() Загрузка specs/*.json (валидация по схеме)
loadCases() Загрузка cases/*.json (валидация по схеме)
│
▼
Сборка CodegenInput { tokens: tokenSet, specs, cases, version }
│
▼
Удаление всего dist/ и пересоздание
│
▼
Последовательное выполнение 5 target'ов ──► android → ios → harmony → c → docs
│ Каждый target.generate(input) возвращает GeneratedFile[]
▼
Покомандная запись файлов на диск по dist/<outDir>/<relativePath>
Константа Значение
ROOT Корень репозитория (два уровня вверх от import.meta.dirname)
DIST <ROOT>/dist
targets [androidTarget, iosTarget, harmonyTarget, cTarget, docsTarget], порядок фиксирован
function main(): void

Единственная точка входа (index.ts не экспортирует сущностей, main() — внутренняя функция, вызываемая прямо в конце файла). Шаги:

  1. readVersion() читает номер версии из package.json
  2. loadTokenFiles() загружает токены
  3. resolveTokens(files) разрешает ссылки, возвращает tokenSet
  4. loadSpecs() / loadCases() загружают контракты и сценарии
  5. Сборка CodegenInput
  6. При existsSync(DIST) выполняется rmSync(DIST, { recursive: true }) — сначала удалить, потом создать, чтобы артефактов без остатка
  7. Для каждого target’а вызывается generate(input), файлы пишутся по dist/<outDir>/<relativePath>, для каждого артефакта печатается лог [target] path
  8. Последней строкой подводятся итоги: количество target’ов, количество файлов, версия

В комментарии-преамбуле файла явно зафиксирована красная линия 1: генерируются только каркасы токенов, никакой реализации UI.

Ниже — четыре наиболее часто используемых в конвейере интерфейса; полный справочник по всем 16 экспортируемым типам — в Определения типов types.ts.

interface CodegenTarget {
name: string // Префикс для логов, например 'android'
outDir: string // Имя подкаталога внутри dist, например 'android'
generate(input: CodegenInput): GeneratedFile[]
}

Каждый target платформы реализует этот интерфейс. Добавить платформу = добавить target и поместить его в массив targets.

interface CodegenInput {
tokens: TokenSet // Разрешённое множество светлых токенов + переопределения тёмной темы
specs: ComponentSpec[] // В данный момент не используется ни одним target'ом (зарезервировано под будущую генерацию документации/тестов компонентов)
cases: ComponentCases[] // То же
version: string // Номер версии из package.json; записывается в заголовочный комментарий каждого артефакта
}
interface GeneratedFile {
relativePath: string // Путь вывода относительно dist/<outDir>/
content: string
}
interface TokenSet {
tokens: ResolvedToken[] // Светлые токены (отсортированы по path в лексикографическом порядке)
byPath: Map<string, ResolvedToken> // Быстрый поиск по пути
dark: DarkOverrides // path -> значение переопределения тёмной темы
}
target Количество файлов
android 2 (LhTokens.kt + LhDarkTokens.kt)
ios 2~3 (+ LhShadow.swift, при наличии токенов теней)
harmony 2~3 (+ LhShadow.ets)
c 2
docs 3

Файлы теней для ios / harmony генерируются только при наличии токенов shadow, поэтому общее количество файлов зависит от содержимого токенов; ориентируйтесь на фактические артефакты в dist/.

Модуль Ответственность
load.ts Загрузка и структурная валидация
resolve.ts Разрешение ссылок и слияние тёмной темы
format.ts Разбор нейтральных значений и форматирование под платформы
tree.ts Из плоского во вложенное
render.ts Рендеринг шаблонов
types.ts Все определения типов
targets/ Пять target’ов платформ
templates/ 7 handlebars-шаблонов

Copyright © 2024-2026 FengMo WenXue