f8b21af4be
10_Wiki/Topics 대규모 정리: - 오류 캡처/미완성 stub 문서 227개 제거 - 교차폴더 중복 43클러스터 병합 (63파일 → redirect) - 링크명 정규화: 깨진 링크 수정·redirect 직결·개념 매핑 ~2,400건 - 카테고리 MOC 6개 신규 생성 - Graph 섹션 미해결 related-keyword 링크 10,058건 제거 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7.8 KiB
7.8 KiB
id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
| id | title | category | status | canonical_id | aliases | duplicate_of | source_trust_level | confidence_score | verification_status | tags | raw_sources | last_reinforced | github_commit | tech_stack | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| wiki-2026-0508-style-dictionary-pipelines | Style Dictionary Pipelines | 10_Wiki/Topics | verified | self |
|
none | A | 0.9 | applied |
|
2026-05-10 | pending |
|
Style Dictionary Pipelines
매 한 줄
"매 Style Dictionary 는 design token (JSON) 을 platform 별 산출물 (CSS/iOS/Android/JSON) 로 transform 하는 build tool". Amazon 발 (2017), v4 (2024) 에서 ESM + DTCG 표준 지원. 2026 기준 Figma Variables → Tokens Studio → Style Dictionary → multi-platform output 의 typical pipeline. CI/CD 통합으로 매 design 변경 → automatic code propagation.
매 핵심
매 token 계층
- Reference (primitive):
color.blue.500,size.4 - System (alias):
color.brand.primary→{color.blue.500} - Component:
button.bg.primary→{color.brand.primary}
매 transform / format
- transform: token value 변환 (px→rem, hex→rgba)
- format: output file 생성 (CSS vars, TS, iOS swift, Android XML)
- filter: token subset 선택
- action: 매 build side-effect (e.g. asset copy)
매 응용
- Multi-platform design system (web + iOS + Android).
- Theming (light/dark, brand variants).
- Figma → code synchronization.
- Component library token consumer.
💻 패턴
Token JSON (DTCG format)
// tokens/color.json
{
"color": {
"blue": {
"500": { "$value": "#3b82f6", "$type": "color" },
"600": { "$value": "#2563eb", "$type": "color" }
},
"brand": {
"primary": { "$value": "{color.blue.500}", "$type": "color" }
}
}
}
config.ts (v4)
// config.ts
import StyleDictionary from "style-dictionary";
const sd = new StyleDictionary({
source: ["tokens/**/*.json"],
platforms: {
css: {
transformGroup: "css",
buildPath: "build/css/",
files: [{ destination: "tokens.css", format: "css/variables" }],
},
ts: {
transformGroup: "js",
buildPath: "build/ts/",
files: [
{ destination: "tokens.ts", format: "javascript/es6" },
{ destination: "tokens.d.ts", format: "typescript/es6-declarations" },
],
},
ios: {
transformGroup: "ios-swift",
buildPath: "build/ios/",
files: [{ destination: "Tokens.swift", format: "ios-swift/class.swift" }],
},
android: {
transformGroup: "android",
buildPath: "build/android/",
files: [{ destination: "tokens.xml", format: "android/resources" }],
},
},
});
await sd.buildAllPlatforms();
Custom transform (px → rem)
import StyleDictionary from "style-dictionary";
StyleDictionary.registerTransform({
name: "size/pxToRem",
type: "value",
filter: (t) => t.$type === "dimension" && String(t.$value).endsWith("px"),
transform: (t) => `${parseFloat(t.$value) / 16}rem`,
});
Custom format (Tailwind theme extension)
StyleDictionary.registerFormat({
name: "tailwind/theme",
format: ({ dictionary }) => {
const colors: Record<string, any> = {};
for (const t of dictionary.allTokens) {
if (t.$type !== "color") continue;
const path = t.path.join(".");
colors[path] = t.$value;
}
return `module.exports = ${JSON.stringify({ theme: { extend: { colors } } }, null, 2)};`;
},
});
Theme variants (light/dark)
// tokens/themes/light.json — refs color/blue/500
// tokens/themes/dark.json — overrides
const themes = ["light", "dark"];
for (const theme of themes) {
const sd = new StyleDictionary({
source: ["tokens/base/**/*.json", `tokens/themes/${theme}.json`],
platforms: {
css: {
transformGroup: "css",
buildPath: "build/css/",
files: [{
destination: `${theme}.css`,
format: "css/variables",
options: { selector: `[data-theme=${theme}]` },
}],
},
},
});
await sd.buildAllPlatforms();
}
CI/CD pipeline (GitHub Actions)
# .github/workflows/tokens.yml
name: Build Tokens
on:
push:
branches: [main]
paths: ["tokens/**", "config.ts"]
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 22, cache: pnpm }
- run: pnpm install --frozen-lockfile
- run: pnpm tsx config.ts
- name: Commit built tokens
run: |
git config user.name "tokens-bot"
git config user.email "bot@example.com"
git add build/
git diff --cached --quiet || git commit -m "chore(tokens): rebuild [skip ci]"
git push
Figma → Tokens Studio → SD
# tokens-studio plugin pushes to GitHub:
# tokens.json (single file)
# SD config consumes via custom parser
npx @tokens-studio/sd-transforms init
import StyleDictionary from "style-dictionary";
import { register } from "@tokens-studio/sd-transforms";
register(StyleDictionary, { excludeParentKeys: true });
const sd = new StyleDictionary({
source: ["tokens.json"],
preprocessors: ["tokens-studio"],
platforms: { css: { /* ... */ } },
});
Validation step
// scripts/validate-tokens.ts
import { readFileSync } from "node:fs";
import { z } from "zod";
const TokenSchema = z.object({
$value: z.union([z.string(), z.number()]),
$type: z.enum(["color", "dimension", "fontFamily", "fontWeight", "duration"]),
});
function walk(obj: any, path: string[] = []) {
if ("$value" in obj) {
TokenSchema.parse(obj);
return;
}
for (const [k, v] of Object.entries(obj)) walk(v, [...path, k]);
}
walk(JSON.parse(readFileSync("tokens.json", "utf-8")));
console.log("매 tokens valid");
Storybook integration
// .storybook/preview.ts
import "../build/css/light.css";
import "../build/css/dark.css";
export const globalTypes = {
theme: {
name: "Theme",
defaultValue: "light",
toolbar: { items: ["light", "dark"] },
},
};
export const decorators = [
(Story, ctx) => {
document.documentElement.dataset.theme = ctx.globals.theme;
return Story();
},
];
매 결정 기준
| 상황 | Approach |
|---|---|
| Web only, simple | CSS vars + Tailwind theme |
| Web + iOS + Android | Style Dictionary |
| Figma 동기화 필수 | Tokens Studio + SD |
| 1-person project | 매 overkill — CSS vars 직접 |
| Theme variants | per-theme builds + selector |
기본값: Style Dictionary v4 + DTCG JSON + GitHub Actions + multi-platform output. Figma 동기화면 Tokens Studio 추가.
🔗 Graph
- 부모: Design Tokens · Design System
- 변형: Tokens Studio
- Adjacent: Figma Variables · CSS_Architecture_and_Styling
🤖 LLM 활용
언제: design system bootstrap, multi-platform theming, Figma → code pipeline. 언제 X: 매 single-file CSS vars 면 충분한 작은 site. Component-only library without theming.
❌ 안티패턴
- Hard-coded colors: 매 token 우회 → consistency 무너짐.
- No reference layer: 매 component token 이 직접 hex → theme 변경 어려움.
- Manual sync from Figma: 매 design drift. 매 Tokens Studio + plugin.
- No CI build: 매 local 만 build → mismatched committed output.
- Token explosion: 매 100s of brand-specific tokens 양산. Hierarchical reference 사용.
🧪 검증 / 중복
- Verified (style-dictionary v4 docs, DTCG spec draft, 2026).
- 신뢰도 A.
🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Style Dictionary pipelines canonical full content |