parseDesignTokens
从 Excel 设计规范文件解析设计令牌,支持基础颜色、组合颜色、圆角、字体、字号、行高、文字、阴影、间距等多种令牌类型。
前置依赖
依赖参数
| 参数名 | 类型 | 说明 |
|---|---|---|
deps.XLSX | XLSXLibrary | XLSX 库实例,用于读取和解析 Excel 文件 |
deps.mixColors | (baseColor: string, overlayColor: string, overlayOpacity: number) => string | 混合颜色计算函数,用于处理颜色叠加表达式 |
环境要求
- xlsx: Excel 文件解析库
- 设计令牌模块: mixColors 函数(同模块内)
bash
npm install xlsx
# mixColors 来自 shared/functions/design-tokens/mixColors函数签名
typescript
import type { XLSXLibrary } from '../../../references/xlsx.d'
export type TokenMap = Record<string, string>
export type Logger = {
/** 日志输出函数 */
log: (message: string) => void
}
/**
* 解析设计令牌的依赖接口
*/
export interface ParseDesignTokensDeps {
/** XLSX 库实例,用于读取Excel文件 */
XLSX: XLSXLibrary
/** 混合颜色计算函数 */
mixColors: (baseColor: string, overlayColor: string, overlayOpacity: number) => string
}
/**
* 解析设计令牌Excel文件
*
* 从Excel文件中解析设计令牌,支持基础颜色、组合颜色、圆角、字体、字号、行高、文字、阴影、间距等多种令牌类型。
*
* @param filePath - Excel文件路径
* @param deps - 环境依赖,包含XLSX库和颜色混合函数
* @param logger - 可选的日志记录器,用于输出解析过程信息
* @returns 解析后的令牌映射对象,键为令牌名称,值为令牌值(颜色为8位hex格式)
*
* @example
* ```typescript
* import * as XLSX from 'xlsx'
* import { mixColors } from 'zcw-shared/functions/design-tokens/mixColors'
* import { parseDesignTokens } from 'zcw-shared/functions/design-tokens/parseDesignTokens'
*
* const tokens = parseDesignTokens('/path/to/design-tokens.xlsx', {
* XLSX,
* mixColors
* }, {
* log: console.log
* })
*
* console.log('解析的令牌数量:', Object.keys(tokens).length)
* console.log('品牌色:', tokens['brand-color']) // "#0077FFFF"
* ```
*/
export function parseDesignTokens(
filePath: string,
deps: ParseDesignTokensDeps,
logger?: Logger
): TokenMap参数
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
filePath | string | 是 | Excel 文件的绝对或相对路径 |
deps | ParseDesignTokensDeps | 是 | 环境依赖,包含 XLSX 库和颜色混合函数 |
logger | Logger | 否 | 可选的日志记录器,输出详细的解析过程信息 |
返回值
| 类型 | 说明 |
|---|---|
TokenMap | 解析后的设计令牌映射对象,格式为 { [tokenName: string]: string } |
令牌值格式:
- 颜色值:8 位十六进制格式(如
#0077FFFF) - 尺寸值:CSS 单位(如
4px、1.5) - 复合样式:JSON 字符串(如
{"fontWeight":"400","fontSize":"16px"}) - CSS 变量引用:
var(--token-name)格式
工作原理
解析流程
- 文件读取:使用
deps.XLSX.readFile读取 Excel 文件 - 工作表枚举:遍历所有工作表(Sheet),识别令牌类型
- 名称标准化:处理工作表命名变体(如
字号-pc、文字_m→字号) - 类型识别:根据工作表名选择解析策略
- 数据提取:使用
XLSX.utils.sheet_to_json转换为行数据 - 令牌解析:
- 基础类型:直接键值对映射
- 颜色处理:RGBA 转 8 位 hex,混合表达式计算
- 复合类型:构建 JSON 对象(如文字样式)
- 指针解析:递归解析
var(--token-name)引用 - 结果返回:完整的
TokenMap对象
支持的工作表格式
| 工作表名称 | 数据格式 | 示例 | 输出格式 |
|---|---|---|---|
基础颜色 | 两列(令牌名, 色值) | brand-color-1 | #0077FFbrand-color-2 | brand-color-1 + #000000 20% | #0077FFFF#005CB3FF |
组合颜色 | 三列(令牌名, 描述, 引用) | primary | 主色 | brand-color-6hover-primary | 悬停色 | primary + #000000 10% | var(--brand-color-6)#0066E6FF |
圆角 | 两列(令牌名, 尺寸) | radius-small | 4pxradius-large | 16px | 4px16px |
字体 | 两列(令牌名, 字体族) | font-family-base | -apple-system, BlinkMacSystemFont | -apple-system, BlinkMacSystemFont |
字号 | 两列(令牌名, 尺寸) | font-size-xs | 12pxfont-size-xl | 24px | 12px24px |
行高 | 两列(令牌名, 倍数值) | line-height-normal | 1.5line-height-tight | 1.2 | 1.51.2 |
文字 | 四列(令牌名, 字重, 字号引用, 行高引用) | text-body | 400 | font-size-base | line-height-normal | {"fontWeight":"400","fontSize":"var(--font-size-base)","lineHeight":"var(--line-height-normal)"} |
阴影 | 两列(令牌名, 阴影描述) | shadow-sm | 0 1px 2px rgba(0,0,0,0.05) | 0 1px 2px rgba(0,0,0,0.05) |
间距 | 两列(令牌名, 尺寸) | spacer-xs | 4pxspacer-xl | 32px | 4px32px |
工作表名称兼容性:
- 支持平台后缀:
字号pc、文字-m、基础颜色_h5等 - 支持分隔符:
基础颜色_移动端、字号_PC版等 - 自动标准化为规范名称(如
基础颜色、字号)
特殊处理
颜色混合表达式
支持在基础颜色工作表中使用混合表达式:
brand-color-dark: brand-color-base + #000000 30%→ 计算后为 8 位 hexoverlay-color: #0077FF 80%→ 转换为rgba(0, 119, 255, 80%)或 8 位 hex
指针解析
支持嵌套的 var 引用解析:
primary→var(--brand-color-6)→#0077FFhover-primary→var(--primary) + #000000 10%→ 计算混合色
复合文字样式
文字工作表支持多列复合格式:
- 列 1:令牌名称(如
text-button) - 列 2:字重(如
500) - 列 3:字号引用(如
font-size-md) - 列 4:行高引用(如
line-height-normal)
异常
| 错误类型 | 触发条件 | 错误信息 |
|---|---|---|
Error | mixColors 计算失败 | 通过 logger 输出,函数返回原始表达式 |
Warning | 未知工作表类型 | 通过 logger 警告,跳过该工作表 |
Warning | 混合颜色格式错误 | 通过 logger 警告,返回原始值 |
Warning | 指针解析循环引用 | 通过 visited Set 检测,返回当前值 |
错误恢复策略:
- 宽容解析:无效数据行会被过滤,函数继续处理其他工作表
- 日志记录:所有异常通过 logger 输出详细信息
- 部分成功:单个工作表解析失败不影响其他工作表
使用示例
基础用法
typescript
import * as XLSX from 'xlsx'
import { mixColors } from 'zcw-shared/functions/design-tokens/mixColors'
import { parseDesignTokens } from 'zcw-shared/functions/design-tokens/parseDesignTokens'
// 基础解析
const tokens = parseDesignTokens('./design-tokens.xlsx', {
XLSX,
mixColors
})
// 查看解析结果
console.log('所有令牌:', tokens)
console.log('品牌色:', tokens['brand-color']) // "#0077FFFF"
console.log('圆角小:', tokens['radius-small']) // "4px"
console.log('文字样式:', tokens['text-body']) // JSON 字符串详细日志模式
typescript
import * as XLSX from 'xlsx'
import { mixColors } from 'zcw-shared/functions/design-tokens/mixColors'
import { parseDesignTokens } from 'zcw-shared/functions/design-tokens/parseDesignTokens'
// 启用详细日志
const tokens = parseDesignTokens('./design-tokens.xlsx', {
XLSX,
mixColors
}, {
log: (message: string) => {
if (message.includes('正在解析工作表:')) {
console.log(`📋 ${message}`)
} else if (message.includes('解析完成')) {
console.log(`🎉 ${message}`)
} else if (message.includes('混合结果')) {
console.log(`🎨 ${message}`)
}
}
})
// 输出示例:
/*
📋 正在解析工作表: 基础颜色
🎨 解析基础混合颜色: brand-color-2 -> #005CB3FF
📋 正在解析工作表: 圆角
📝 存储圆角: radius-small = 4px
...
🎉 设计令牌解析完成,总计 45 个令牌
*/与 buildTokens 集成
typescript
import * as XLSX from 'xlsx'
import * as fs from 'fs'
import * as path from 'path'
import { mixColors } from 'zcw-shared/functions/design-tokens/mixColors'
import { parseDesignTokens } from 'zcw-shared/functions/design-tokens/parseDesignTokens'
import { generateCSSVariables, generateJSVariables } from 'zcw-shared/functions/design-tokens/generateVariables'
// 手动解析流程(不使用文件系统)
const tokens = parseDesignTokens('./design-tokens.xlsx', {
XLSX,
mixColors
})
// 生成 CSS
const cssContent = generateCSSVariables(tokens, 'manual')
fs.writeFileSync('./manual-tokens.css', cssContent)
// 生成 JS
const jsContent = generateJSVariables(tokens, 'manualTokens')
fs.writeFileSync('./manual-tokens.js', jsContent)
console.log('手动解析完成,生成 2 个文件')
console.log('令牌示例:', {
brandColor: tokens['brand-color'],
primaryColor: tokens['primary'],
radiusSmall: tokens['radius-small']
})错误处理示例
typescript
import * as XLSX from 'xlsx'
import { mixColors } from 'zcw-shared/functions/design-tokens/mixColors'
import { parseDesignTokens } from 'zcw-shared/functions/design-tokens/parseDesignTokens'
try {
// 无效的 Excel 文件
const tokens = parseDesignTokens('./invalid-file.xlsx', {
XLSX,
mixColors
})
} catch (error) {
// 应该捕获到文件读取错误
console.error('文件读取失败:', error)
}
// 解析过程错误(格式错误的工作表)
const tokens = parseDesignTokens('./design-tokens.xlsx', {
XLSX,
mixColors
}, {
log: (message: string) => {
if (message.includes('⚠️') || message.includes('❌')) {
console.warn(message) // 警告:未知工作表或混合格式错误
}
}
})
// 解析仍然成功,但 logger 会显示警告信息
console.log('解析完成,尽管有格式警告:', Object.keys(tokens).length)日志输出示例
当启用详细日志时,解析过程会输出:
🔍 开始解析设计令牌文件: ./design-tokens.xlsx
📖 Excel文件读取成功
📊 发现工作表: 基础颜色, 组合颜色, 圆角, 字号, 文字
📋 正在解析工作表: 基础颜色
🎨 解析基础颜色...
📝 存储基础颜色: brand-color-1 = #0077FF
🎨 计算混合颜色: brand-color-1 + #000000 20%
✅ 混合结果: #005CB3FF
🎨 解析基础混合颜色: brand-color-2 -> #005CB3FF
📋 正在解析工作表: 组合颜色
🔗 解析组合颜色...
🔄 解析组合颜色: primary -> var(--brand-color-6)
🔍 指针解析路径: brand-color-6 -> #0077FF
🔄 解析组合颜色: primary -> var(--brand-color-6)
📋 正在解析工作表: 圆角
📐 解析圆角令牌...
📝 存储圆角: radius-small = 4px
📊 工作表 圆角 共有 5 行数据
🎉 设计令牌解析完成,总计 45 个令牌日志级别说明:
- 📖:基本信息(如文件读取成功)
- 📊:结构信息(如工作表数量)
- 🎨:颜色处理(如混合计算)
- 📝:数据存储(如令牌映射)
- 🔍:指针解析(如引用链路)
- ⚠️:警告(如格式不匹配)
- ❌:错误(如计算失败)
parseDesignTokens 是设计令牌模块的核心解析引擎,支持复杂的 Excel 格式和智能的令牌类型识别,确保设计规范能够准确转换为可用的 TokenMap。