
Label Studio 前端 Design Tokens 轉換工具從 Figma JSON 到 CSS 變量與 Tailwind 主題的工程化實踐【免費下載鏈接】label-studioLabel Studio is a multi-type data labeling and annotation tool with standardized output format項目地址: https://gitcode.com/GitHub_Trending/la/label-studio在 Label Studio 的前端倉庫web/目錄基于 bun Vite Tailwind CSS 的 monorepo中設計系統通過一條自動化流水線落地設計師在 Figma 中維護的 Design Tokens 以design-tokens.json形式導出再由 design-tokens-converter 轉換腳本批量編譯為 CSS 變量文件和供 Tailwind 消費的 JavaScript 模塊從而同時支撐 CSS 直接取值var(--color-...)與 Tailwind 語義化類名text-primary-content兩種使用方式。讀完本文你將掌握該轉換工具的完整用法、design-tokens.json的集合結構與參考引用解析機制、明暗主題與響應式字體的輸出策略以及產物如何接入 Tailwind 配置。一、輸入格式Figma 導出的 design-tokens.json轉換的輸入是放置在web/工作區根目錄的 design-tokens.json約 180KB當前倉庫中已包含真實設計數據。從該文件的頂層結構看它包含四個集合collection頂層鍵含義處理函數源碼位置color語義化顏色neutral / primary / accent 等帶 light/dark 模式processColorTokensprimitives基礎色板$color、基礎間距$spacing、基礎字體$typography、圓角$corner-radiusprocessPrimitiveColors/processPrimitiveSpacing/processPrimitiveTypography/processPrimitiveCornerRadiussizing派生尺寸類 token含嵌套命名如圓角processSizingTokenstypography語義化排版 tokenfont-family、font-size、font-weight、line-height、letter-spacing桌面 移動模式processTypographyTokens每個 token 節點的典型形態是{ $type: color, $value: {primitives.$color.$sand.100}, $variable_metadata: { modes: { light: ..., dark: ... } } }$type標明值類型$value可能是字面量也可能是形如{primitives.$color.$sand.100}的token 引用。例如當前倉庫中color下的--color-neutral-surface即引用{primitives.$color.$sand.100}primary系列則引用$grape色族——引用解析是該工具最核心的能力之一見下文。二、使用方法三步完成轉換按 README 的說明流程如下從 Figma 導出 design tokens 為design-tokens.json放到label-studio/web/目錄前端工作區根目錄運行轉換腳本。README 中給出的入口命令是nx design-tokens ui在當前倉庫中等價入口已改為 bun 腳本——web/package.json 中定義了design-tokens: bun tools/design-tokens-converter/design-tokens-converter.mjs因此也可以直接在web/下執行bun run design-tokens兩種方式最終都運行同一個腳本 design-tokens-converter.mjs其 package.json 將其同時聲明為包humansignal/design-tokens-converter的 bin 可執行文件另有一個 無擴展名的入口 shim 僅import該 .mjs 文件便于直接node調用生成覆蓋寫入兩個產物web/libs/ui/src/tokens/tokens.prefix.css—— 明/暗主題 CSS 變量 移動端響應式排版變量web/libs/ui/src/tokens/tokens.js—— 供 Tailwind 配置消費的 JS 對象。腳本自身會先通過findWorkspaceRoot()源碼 L74-L86從腳本所在目錄逐級向上查找以web結尾的目錄定位工作區根找不到則拋出Could not find workspace root directory隨后校驗design-tokens.json是否存在缺失時打印The design-tokens.json file does not exist at ...并以退出碼 1 結束源碼 L1110-L1159。三、轉換管線從 JSON 到兩份產物的源碼剖析processDesignVariables()源碼 L150-L203是整個管線的調度中心它按固定順序處理各集合最終產出{ cssVariables: { light, dark, mobile }, jsTokens: { colors, spacing, typography, cornerRadius } }的中間結構再分別交給generateCssContent()L956-L983與generateJsContent()L1094-L1105生成文件。幾個值得關注的實現細節3.1 參考引用解析{primitives...}不落地為字面量resolveReference()L886-L913按.分段沿對象導航解析{...}形式的引用。但對指向基礎值的引用轉換器更聰明的做法是在 CSS 中保留為變量鏈而非解算成字面量當引用的目標是primitives集合時直接改寫為對應 CSS 變量。例如--corner-radius-*引用 spacing 時輸出--xxx: var(--spacing-xxx)L391-L405顏色引用{primitives.$color.$sand.100}則經resolveColor()L835-L878改寫為var(--color-sand-100)。這樣基礎色板只定義一次語義 token 全部引用它改基礎值即全局生效——產物tokens.prefix.css中可以看到這種結構:root { --color-neutral-surface: var(--color-sand-100); --color-primary-surface: var(--color-grape-700); --spacing-50: 0.125rem; --font-size-14: 0.875rem; /* ... */ }引用解析失敗時路徑在 JSON 中不存在resolveReference會原樣返回未解析的字符串不會中斷轉換屬于容錯設計。3.2 單位換算與字體家族規范化數值類 token 統一經convertToRem()L100-L107換算以 16px 為基準保留 4 位小數并去掉尾隨零14px → 0.875rem0保持無單位字體家族列表經formatFontFamilyForCss()L127-L143格式化具體字體名加雙引號sans-serif、monospace、system-ui等 CSS 通用家族按規范保持不加引號Figma 會把斜體字重如Medium Italic作為非數值 font-weight 導出轉換器會跳過這些條目isFontWeightItalicVariantL528-L535改而在 CSS 中直接注入--font-style-normal: normal與--font-style-italic: italic兩條變量L364-L375。3.3 顏色輸出RGB 化 -raw變量 暗色模式顏色 token 經hexToRgb()L765-L794從 3/6 位 hex 轉為rgb(r g b)格式目的是配合 CSS 的rgb(var(--x) / alpha)用法支持透明度。此外對名稱包含primary、shadow、outline、surface、accent、background這組關鍵詞的語義色RAW_COLOR_VALUE_TOKENSL64還會額外輸出--color-xxx-raw: r g b形式的裸三元組變量例如產物中的--color-neutral-surface: var(--color-sand-100); --color-neutral-surface-raw: 249 248 246;-raw變量專門用于rgb(var(--color-neutral-surface-raw) / 0.5)這類半透明寫法源碼注釋見 L723-L724。暗色模式則依據$variable_metadata.modes.dark輸出到[data-color-schemedark]選擇器塊——當前產物中該塊位于tokens.prefix.css第 567 行起與:root塊一一對應。3.4 響應式排版只輸出“與桌面不同的”移動值typography集合的 token 帶有desktop與mobile兩種模式與顏色的 light/dark 類似。processTokenCollection()L510-L562會為每個 token 計算桌面值寫入:root再取$variable_metadata.modes.mobile解析出移動值僅當移動值與桌面值不同時才追加進media (max-width: 767px)塊常量MOBILE_MEDIA_QUERYL67媒體查詢上限對齊 Tailwind 的md斷點768px。當前產物中該塊第 866 行起形如media (max-width: 767px) { :root { --font-size-body-medium: var(--font-size-14); --font-size-title-large: var(--font-size-22); --line-height-label-medium: var(--line-height-20); /* ... 僅桌面與移動不同的 token ... */ } }由于 Tailwind 工具類與Typography組件最終都通過var(--font-size-body-medium)這類語義變量解析768px 以下會自動應用移動端字號無需逐組件覆蓋README 也建議只有在刻意切換到“另一個”token 以調整布局密度時才顯式使用max-md:text-*。3.5 已知問題與尾差修正Figma 源數據中圓角集合寫作corder-radiustypo轉換器在processSizingTokens()的嵌套 key 拼接中做了replace(corder, corner)修正L436-L437確保產物中 CSS 變量名與 JS key 都是正確的corner-radius。3.6 JS 產物面向 Tailwind 的結構整形generateJsContent()生成的tokens.js頭部聲明“此文件由工具生成請改design-tokens.json而不是本文件”。序列化前先經過兩步整形mergePrimitiveValues()L1058-L1087把各級primitive子樹向上合并使最終對象按類別扁平化transformColorObjectForTailwind()L990-L1034把surface-hover這類連字符變體重組為嵌套對象——基礎名下的默認值收進DEFAULT變體作為兄弟屬性從而匹配 Tailwind 的colors擴展結構。實際產物 tokens.js 開頭即為const designTokens { colors: { neutral: { surface: { DEFAULT: var(--color-neutral-surface), hover: var(--color-neutral-surface-hover), active: var(--color-neutral-surface-active), inset: var(--color-neutral-surface-inset), }, /* ... */ }, /* primary / accent / spacing / typography / cornerRadius ... */ }, }; export default designTokens;序列化函數serializeToJsLiteral()L29-L58會盡量輸出不帶引號的合法標識符 key數字 key 輸出為數字字面量以匹配倉庫 Biome 的代碼風格約束。四、產物使用方式CSS 變量與 Tailwind 雙通道4.1 在樣式表中導入 CSS 變量import libs/ui/src/tokens/tokens.prefix.css;之后即可在任意樣式中使用語義變量均取自 README 示例變量名可在產物中逐一核對存在/* 顏色 */ .my-element { color: var(--color-primary-content); background-color: var(--color-neutral-surface); } /* 間距 */ .padded { padding: var(--spacing-base); margin: var(--spacing-wide); } /* 排版 */ .heading { font-family: var(--font-family-sans); font-size: var(--font-size-24); line-height: var(--line-height-32); font-weight: var(--font-weight-bold); } /* 圓角 */ .rounded { border-radius: var(--corner-radius-medium); }暗色模式通過在body上切換data-color-schemedark屬性生效對應產物中的[data-color-schemedark]塊body>// tailwind.config.js (ESM) import designTokens from ./libs/ui/src/tokens/tokens.js; export default { theme: { extend: { colors: { ...designTokens.colors, }, spacing: designTokens.spacing, fontSize: designTokens.typography.fontSize, lineHeight: designTokens.typography.lineHeight, letterSpacing: designTokens.typography.letterSpacing, fontFamily: designTokens.typography.fontFamily, fontWeight: designTokens.typography.fontWeight, borderRadius: designTokens.cornerRadius, }, }, };CommonJS 環境下用require(./libs/ui/src/tokens/tokens.js).default獲取默認導出。當前倉庫的實際接入方式與之同構web/tailwind.config.js 只有一行轉發到 libs/ui/src/tailwind.config.js后者用createRequire加載同目錄的./tokens/tokens.js并在theme.extend中展開...tokens.colors、...tokens.typography.fontSize、...tokens.spacing等L57-L129。由于每個工具類的值本身就是var(--xxx)字符串Tailwind 類名最終也走 CSS 變量天然獲得暗色模式與響應式排版能力。接入后即可直接使用語義類名div classtext-primary-content bg-neutral-surface…/div !-- 顏色 -- div classp-base my-large…/div !-- 間距 -- h1 classfont-sans text-24 leading-32 font-bold…/h1 !-- 排版 -- div classrounded-medium…/div !-- 圓角 --libs/ui/src/tokens/目錄下的 tokens.stories.tsx 還配套了 Storybook 示例可通過 web/package.json 的storybook:serve端口 4400啟動查看同目錄的colors.prefix.css、typography.prefix.css是拆分主題文件prefix命名對應倉庫的 postcss-prefix-lsf.cjs 前綴化方案。五、設計 token 更新流程與注意事項當 Figma 側產出新版 token 時README 的 “Updating Design Tokens” 一節用新導出的文件替換工作區根目錄的design-tokens.json重新運行轉換命令nx design-tokens ui或bun run design-tokens兩份產物文件即被完整重新生成不需要手工修補。使用上的注意事項兩個產物文件都帶DO NOT EDIT DIRECTLY頭注釋任何改動都應回到design-tokens.json再重新生成腳本要求工作區根目錄名以web結尾且design-tokens.json必須存在且是合法 JSON否則進程以非零碼退出并打印診斷信息移動端字號只覆蓋“桌面/移動不一致”的 token若某 token 兩側一致產物中不會出現在媒體查詢塊里這是預期行為圓角的corder-radius拼寫問題只在sizing集合內做修正L437如未來 Figma 導出結構變化例如鍵名調整需要回到processDesignVariables()的各分支條件核對。六、小結Label Studio 前端的這條 token 流水線體現了“設計數據即單一事實源”的常見做法Figma 導出 JSON → 一次性編譯 → CSS 變量tokens.prefix.css JS 主題對象tokens.js雙產物 → 同時服務原生 CSS 與 Tailwind。理解它的內部實現引用改寫成變量鏈、hex 轉 RGB -raw透明度通道、data-color-scheme暗色塊、768px 斷點的差異化排版輸出、Tailwind 顏色結構整形既有助于排查“某個類名/變量不存在”類問題也為在其他項目中自建同類工具提供了可參照的完整樣本。【免費下載鏈接】label-studioLabel Studio is a multi-type data labeling and annotation tool with standardized output format項目地址: https://gitcode.com/GitHub_Trending/la/label-studio創作聲明:本文部分內容由AI輔助生成(AIGC),僅供參考