Każdy eksport figmascope zawiera tokens.json. To pomost między wizualnymi wartościami Figmy a typowanymi stałymi, których potrzebuje twój kod. Ten artykuł opisuje schemat, sposób nazewnictwa kluczy, co się dzieje gdy plik Figmy nie ma Variables oraz gdzie system tokenów szczerze zawodzi.

Schemat

Struktura najwyższego poziomu ma cztery sekcje:

{
  "spacing": {
    "spacing.4":  { "$value": 4,  "$type": "dimension" },
    "spacing.8":  { "$value": 8,  "$type": "dimension" },
    "spacing.12": { "$value": 12, "$type": "dimension" },
    "spacing.16": { "$value": 16, "$type": "dimension" },
    "spacing.24": { "$value": 24, "$type": "dimension" }
  },
  "radius": {
    "radius.4":  { "$value": 4,  "$type": "dimension" },
    "radius.8":  { "$value": 8,  "$type": "dimension" },
    "radius.12": { "$value": 12, "$type": "dimension" }
  },
  "color": {
    "color.7f5cfe": { "$value": "#7f5cfe", "$type": "color" },
    "color.ffffff": { "$value": "#ffffff", "$type": "color" },
    "color.1a1a2e": { "$value": "#1a1a2e", "$type": "color" }
  },
  "typography": {}
}

Format jest zbliżony do W3C Design Tokens Community Group: każdy token to obiekt z $value i $type. To nie jest ścisła implementacja W3C DTCG — figmascope powstał przed opublikowaniem finalnej specyfikacji i nie implementuje typów złożonych jak fontFamily — ale jest wystarczająco bliski, by narzędzia obsługujące DTCG mogły go parsować z niewielką adaptacją.

Pusty obiekt typography to nie błąd. Jest opisany poniżej.

Nazewnictwo kluczy wywiedzione z wartości

Gdy plik Figmy ma Variables, klucze tokenów pochodzą od nazw Variables ustawionych przez projektanta. spacing.md, color.brand.primary, cokolwiek używa system projektowy.

Gdy plik Figmy nie ma Variables — co dotyczy większości realnych plików Figmy — figmascope spada do nazewnictwa wywiedzionego z wartości. Wartość odstępu 16 staje się spacing.16. Kolor #7f5cfe staje się color.7f5cfe. Promień narożnika 4 staje się radius.4.

To celowy kompromis. Nazwy wywiedzione z wartości są brzydkie, ale stabilne. Są wyprowadzane z faktycznej wartości, więc dwa różne uruchomienia tego samego pliku Figmy produkują ten sam klucz. spacing.16 zawsze oznacza 16dp. Agent może na tym polegać.

Alternatywą byłyby nazwy pozycyjne jak spacing.1, spacing.2 itd. Są kruche — dodaj mniejszą wartość odstępu i wszystko się przesuwa. Nazwy wywiedzione z wartości nie przesuwają się.

Nazwy wywiedzione z wartości to fallback dla plików, które powinny mieć Variables, ale ich nie mają. Jeśli twój system projektowy ma 40 wartości odstępów wymagających semantycznych nazw, nakłoń projektanta do ustawienia Variables. Fallback wnioskowania istnieje dla plików z realnego świata, nie jako zamiennik prawdziwego systemu tokenów. Możesz uruchomić figmascope na własnym pliku, żeby zobaczyć którą ścieżką podąża.

Pole tokensSource i co oznacza

_meta.json zawiera pole tokensSource, które mówi ci jak zostały wyprowadzone tokeny:

WartośćZnaczenie
"figma-variables" Plik Figmy ma Variables i zostały użyte bezpośrednio. Nazwy tokenów są przypisane przez projektanta. Pełne pokrycie.
"inferred-from-frequency" Brak Variables. figmascope przeskanował wszystkie węzły, znalazł często powtarzające się wartości i awansował je do tokenów. Pokrycie zależy od spójności projektu.
"none" Brak Variables i wnioskowanie nie przyniosło niczego użytecznego. tokens.json będzie miał puste lub prawie puste sekcje.

Ostrzeżenie "tokens-inferred-from-frequency" w _meta.json odzwierciedla to. Jeśli je widzisz, pokrycie tokenów jest na zasadzie najlepszych starań.

Gdy tokensSource ma wartość "inferred-from-frequency", algorytm wnioskowania jest następujący: znajdź wszystkie wartości wymiarów pojawiające się w polach padding, gap lub cornerRadius trzech lub więcej węzłów. Awansuj je odpowiednio do tokenów spacing lub radius. Zrób to samo dla kolorów wypełnienia. Wartości pojawiające się tylko raz lub dwa razy są traktowane jako jednorazowe i nie są awansowane.

Działa dobrze dla projektów, które są wewnętrznie spójne. Działa słabo dla projektów eksploracyjnych, gdzie odstępy swobodnie się różnią. Ostrzeżenia w _meta.json istnieją właśnie po to, by agent wiedział, w której sytuacji się znajduje.

Dlaczego typography jest często puste

Tokeny typografii wymagają Figma Variables z typem FLOAT lub STRING, żeby móc być niezawodnie wyodrębnione. Style tekstowe istnieją w Figmie jako style współdzielone, nie Variables, a powierzchnia API dla stylów jest inna niż dla Variables API.

figmascope v0.4 wyodrębnia typografię gdy Variables ją pokrywają. Nie próbuje wnioskowania opartego na częstotliwości dla typografii, ponieważ przydatne tokeny typografii — rodzina czcionek, wysokość linii, odstępy liter, kombinacje wagi — nie mają oczywistych nazw wywiedzionych z wartości tak jak spacing.16. Klucz fontSize.14 jest znacznie mniej użyteczny niż typography.body.small, a generowanie złej nazwy jest gorsze niż nie generowanie żadnej.

Więc wynik jest uczciwy: jeśli twój plik Figmy ma Variables typografii, dostajesz tokeny typografii. Jeśli nie, dostajesz pusty obiekt, a agent jest informowany przez CONTEXT.md, że pokrycie typografii może być częściowe.

// _meta.json
{
  "tokensSource": "inferred-from-frequency",
  "warnings": [
    "tokens-inferred-from-frequency"
  ]
}

Agent to widzi i wie, żeby być ostrożnym przy odwołaniach do tokenów typografii. Generuje kod fallback z jawnymi wartościami i komentarzem TODO zamiast wymyślać nazwę tokenu.

Jak agent używa tokens.json

Ograniczenie w CONTEXT.md brzmi: „Nigdy nie koduj wartości dp na stałe, jeśli token istnieje w zakresie ±2dp." Tolerancja ±2dp obsługuje zaokrąglanie. Jeśli węzeł ma paddingLeft: 15 i istnieje spacing.16, agent używa spacing.16. Jeśli najbliższy token to spacing.24, brak dopasowania — agent używa wartości dosłownej.

Dla kolorów dopasowanie jest dokładne na wartości hex po normalizacji do 6-cyfrowej, małych liter. #7F5CFE pasuje do color.7f5cfe.

Dla promienia narożnika ta sama zasada ±2dp co dla spacing.

Praktyczny wynik dla celu Jetpack Compose wygląda tak:

// Z tokensSource figma-variables
Surface(
    shape = RoundedCornerShape(Radius.radius8),
    color = Color.Brand.Primary
) {
    Column(
        verticalArrangement = Arrangement.spacedBy(Spacing.spacing16),
        modifier = Modifier.padding(horizontal = Spacing.spacing24)
    ) { ... }
}

// Z tokensSource inferred-from-frequency (ten sam wynik wizualny, te same odwołania do tokenów)
Surface(
    shape = RoundedCornerShape(Radius.radius8),
    color = Color.color7f5cfe
) { ... }

Nazwy wywiedzione z wartości są mniej czytelne. Wciąż lepsze niż zakodowane wartości.

Porównanie z innymi podejściami do ekstrakcji tokenów

Natywny panel „Inspect" Figmy pokazuje wartości per-węzeł. Nie ma wyeksportowanego pliku tokenów. Musiałbyś go ręcznie stworzyć lub użyć wtyczki jak Tokens Studio. Oba wymagają wysiłku projektanta i bieżącego utrzymania.

figmascope wyodrębnia tokeny automatycznie przy każdym eksporcie. Jeśli plik się zmieni, wyeksportuj ponownie i tokeny odzwierciedlają aktualny stan. Kompromisem jest to, że bez Variables nazwy są wywiedzione z wartości, a nie semantyczne — ale za każdym razem dostajesz plik tokenów, bez wtyczki ani dodatkowego kroku w przepływie pracy.

Tokens Studio (dawniej integracja Style Dictionary) wymaga, żeby projektant skonfigurował wtyczkę, utrzymywał plik JSON w pliku Figmy i go synchronizował. To właściwe rozwiązanie dla dojrzałego systemu projektowego. Podejście figmascope to właściwe rozwiązanie dla plików, które tam jeszcze nie dotarły, a to większość plików.

Ekstrakcja tokenów to snapshot najlepszych starań tego, co istnieje w pliku. To nie zamiennik systemu projektowego opartego na tokenach. To narzędzie, którego używasz budując w kierunku takiego systemu.

Podłączanie tokens.json do twojej bazy kodu

Struktura JSON jest wystarczająco płaska, że generowanie obiektu Kotlin lub modułu TypeScript z niej jest proste. Prosty skrypt:

// tokens.json → obiekt Kotlin (uproszczony)
const tokens = JSON.parse(fs.readFileSync('tokens.json', 'utf-8'));

let output = 'object Spacing {\n';
for (const [key, token] of Object.entries(tokens.spacing)) {
    const name = key.replace('spacing.', 'spacing').replace('.', '_');
    output += `    val ${name} = ${token.$value}.dp\n`;
}
output += '}';
// → val spacing16 = 16.dp

Jeśli już używasz pipeline'u design tokenów, format zbliżony do W3C jest wystarczająco bliski, żeby wrzucić go do Style Dictionary z niestandardowym transformatorem dla kluczy $value/$type.

Reszta tego, jak tokeny oddziałują z IR, jest opisana w Per-Screen IR. Jak tokeny oddziałują z szerszym kontekstem agenta, zobacz Anatomia CONTEXT.md. Dla przepływu pracy eksportu design tokenów od końca do końca, zobacz Eksport Design Tokenów. Żeby wyeksportować tokeny z własnego pliku Figmy, przejdź do figmascope.dev.